예제 #1
0
 /**
  * Coearce passed value to type stored in $this->type.
  * The output of this function is expected to be passed to QuoteInterface->quote()
  *
  * @param mixed Value to coearce to type
  * @return mixed
  */
 private function coearceToType($value)
 {
     // objects have to support QueryQuoteSafe
     if (is_object($value)) {
         if ($value instanceof SqlInterface) {
             return $value;
         }
         throw new BadTypeException($value, "Needs to implement SqlInterface");
         // null's don't get molested
     } elseif ($value === null) {
         return null;
     }
     $isArray = is_array($value);
     // We're told to expect a array and we don't get one ...
     if ($this->isArray and !$isArray) {
         throw new BadTypeException($value, 'array');
     }
     // Have array ...
     if (is_array($value)) {
         // build a element modifier for the elenents in our array
         $elementModifier = clone $this;
         if (in_array($this->type, ['in', 'array'], true)) {
             $elementModifier->type = null;
         }
         $elementModifier->isArray = false;
         // coearce every value in the array to to the correct type
         $value = array_map(array($elementModifier, 'coearceToType'), $value);
         $class = sprintf("%s\\%sType", __NAMESPACE__, $this->type === 'in' ? 'In' : 'Array');
         return new $class($value);
     }
     // standard types
     switch ($this->type) {
         case null:
             return $value;
         case 'text':
         case 'enum':
         case 'timestamp':
             return (string) $value;
         case 'bool':
             return \Bond\boolval($value);
         case 'oid':
         case 'int':
             return (int) $value;
         case 'identifier':
             return new Identifier($value);
         case 'json':
             return is_string($value) ? $value : json_encode($value);
         case 'varbit':
             return decbin((int) $value);
         case 'bytea':
             return new Bytea($value);
     }
     // char(13)
     if (preg_match('/^char\\(([\\d]+)\\)$/', $this->type, $matches)) {
         return (string) substr($value, 0, $matches[1]);
     }
     return $value;
 }
예제 #2
0
파일: Pg.php 프로젝트: squareproton/bond
 /**
  * Get a postgres runtime parameter
  * @return string
  */
 public function getParameter($parameter)
 {
     self::isParameterAllowed($parameter);
     $value = $this->query(new Raw("SHOW {$parameter}"))->fetch(Result::FETCH_SINGLE);
     return ($value === 'true' or $value === 'false') ? \Bond\boolval($value) : $value;
 }
예제 #3
0
 /**
  * Extract tags from string
  *
  * Tags beginning with %tag: [1,2,3] are json decoded
  * Tags beginning with @tag: value are build in the stanard way
  * Tags can be 'namespaced' with '.'
  *
  * @param string|object String from which to extract comments. If object it must expose ->getComment(). // If you want inheritance it must expose ->getReferences()
  * @return array Comments
  */
 function extract_tags($stringOrObject, $prefix = null)
 {
     // object handling
     if (is_object($stringOrObject)) {
         if (method_exists($stringOrObject, 'getComment')) {
             $string = $stringOrObject->getComment();
         } else {
             throw new BadTypeException($stringOrObject, 'string');
         }
     } else {
         $string = (string) $stringOrObject;
     }
     $regex = "/^\n                    ([%@\$])\n                    ([^\\v:\\[\\]]+)\n                    (\\[\n                       [^\\]]*\n                     \\])?\n                    :\n                    (.*)?\n                   \$\n                   |\n                   ^\n                    ([%@])\n                    (.*)\n                   \$\n                  /mx";
     $output = array();
     if (preg_match_all($regex, $string, $matches, PREG_SET_ORDER)) {
         foreach ($matches as $match) {
             // we got a lone tag no value
             if (isset($match[6])) {
                 $match[2] = $match[6];
                 $match[4] = 'true';
             }
             $key = trim($match[2]);
             $value = trim($match[4]);
             // Namespacing. F*****g hell these were 6 very difficult lines. Be afraid. Seriously. I'm not joking.
             $working = array();
             $refs = array();
             $keys = explode('.', $key);
             foreach (array_reverse($keys) as $k) {
                 $working = array($k => $working);
                 $refs[] =& $working[$k];
             }
             // inheritance?
             if ($value === '@inherit') {
                 throw new \Exception("TODO");
                 if (!is_object($stringOrObject)) {
                     throw new \LogicException("can't inherit off object which doesn't reference another object, see object->get('references')");
                 }
                 // merge only the tags which are required
                 if ($reference = $stringOrObject->get('references')) {
                     $value = \Bond\extract_tags($reference);
                     foreach ($keys as $key) {
                         // no match
                         if (!is_array($value) || !array_key_exists($key, $value)) {
                             // break reference chain. This loop will now do nothing.
                             $working = array();
                         } else {
                             $value = $value[$key];
                         }
                     }
                 } else {
                     // break reference chain. This loop will now do nothing.
                     $working = array();
                 }
             }
             // json decode
             if ($match[1] === '%') {
                 $value = json_decode($value, true);
                 if (json_last_error()) {
                     throw new \UnexpectedValueException("json_decode returned a error when extracting tags `{$value}` in \n `{$string}`\n");
                 }
             } elseif ($match[1] === '$') {
                 $value = call_user_func($value);
             }
             // cast bool-like strings and nulls to their real types
             if (is_string($value)) {
                 if (in_array(strtolower($value), array('t', 'f', 'true', 'false', 'on', 'off'))) {
                     $value = \Bond\boolval($value);
                 } elseif ($value === 'NULL') {
                     $value = 'spanner';
                 }
             }
             // is array()
             if (!empty($match[3])) {
                 if ($match[3] == '[]') {
                     $refs[0][] = $value;
                 } else {
                     $key = trim($match[3], '[]');
                     $refs[0][$key] = $value;
                 }
             } else {
                 $refs[0] = $value;
             }
             // merge working into output
             $output = array_merge_recursive($output, $working);
         }
     }
     // prefix namespace aware
     if (isset($prefix)) {
         foreach (explode('.', $prefix) as $key) {
             if (!is_array($output) || !array_key_exists($key, $output)) {
                 return array();
             } else {
                 $output = $output[$key];
             }
         }
     }
     return $output;
 }
예제 #4
0
 /**
  * Generate a dataType from a Bond\Pg\Catalog\PgAttribute
  * @param Attribute $attribute
  * @return static
  */
 public static function makeFromAttribute(PgAttribute $attribute)
 {
     $name = $attribute->name;
     $entity = $attribute->getRelation()->getEntityName();
     $type = $attribute->getType();
     $fullyQualifiedName = $attribute->getFullyQualifiedName();
     $data = array('isPrimaryKey' => $attribute->isPrimaryKey(), 'isUnique' => $attribute->isUnique(), 'isNullable' => !$attribute->notNull, 'isArray' => $attribute->isArray, 'isInherited' => $attribute->isInherited(), 'type' => $type->getTypeQuery(), 'length' => $attribute->length, 'default' => $attribute->default);
     $data += $attribute->getEntity();
     if ($type->isBool() and in_array(strtolower($data['default']), array('true', 'false'))) {
         $data['default'] = \Bond\boolval($data['default']);
     }
     if ($type->isEnum()) {
         $data['enumName'] = $type->name;
     }
     if ($tags = \Bond\extract_tags($attribute->comment, 'form')) {
         $data['form'] = $tags;
     }
     if ($tags = \Bond\extract_tags($attribute->comment, 'api')) {
         $data += $tags;
     }
     if ($tags = \Bond\extract_tags($attribute->comment, 'filter')) {
         $data['filter'] = $tags;
     }
     if ($tags = \Bond\extract_tags($attribute->comment, 'normality')) {
         $data['isFormChoiceText'] = isset($tags['form-choicetext']);
         $data['isAutoComplete'] = isset($tags['autoComplete']);
     }
     return new static($name, $entity, $fullyQualifiedName, $data);
 }
예제 #5
0
 public function testBoolval()
 {
     $this->assertTrue(\Bond\boolval(true));
     $this->assertTrue(\Bond\boolval(1));
     $this->assertTrue(\Bond\boolval('true'));
     $this->assertTrue(\Bond\boolval('TRUE'));
     $this->assertTrue(\Bond\boolval('True'));
     $this->assertTrue(\Bond\boolval('tTuE'));
     $this->assertTrue(\Bond\boolval('spanner'));
     $this->assertTrue(\Bond\boolval('t'));
     $this->assertTrue(\Bond\boolval('T'));
     $this->assertFalse(\Bond\boolval(false));
     $this->assertFalse(\Bond\boolval(null));
     $this->assertFalse(\Bond\boolval(0));
     $this->assertFalse(\Bond\boolval('false'));
     $this->assertFalse(\Bond\boolval('fAlSE'));
     $this->assertFalse(\Bond\boolval('False'));
     $this->assertFalse(\Bond\boolval('f'));
     $this->assertFalse(\Bond\boolval('F'));
 }