/** * * @param string $sql * @return \ArrayObject * @throws UnsupportedDatatypeException * @throws Exception\AmbiguousColumnException * @throws Exception\ConnectionException */ protected function readColumnsMetadata($sql) { $metadata = new ArrayObject(); $fields = $this->readFields($sql); $type_map = $this->getDatatypeMapping(); foreach ($fields as $idx => $field) { $name = $field->orgname == '' ? $field->name : $field->orgname; $tableName = $field->orgtable; $schemaName = $field->db; $datatype = $field->type; //@codeCoverageIgnoreStart if (!$type_map->offsetExists($datatype)) { throw new UnsupportedDatatypeException("Datatype '{$datatype}' not yet supported by " . __CLASS__); } //@codeCoverageIgnoreEnd $datatype = $type_map->offsetGet($datatype); $column = Column\Type::createColumnDefinition($datatype['type'], $name, $tableName, $schemaName); /* if ($field->name == 'min_time') { var_dump($field); // var_dump($field->flags & MYSQLI_BLOB_FLAG); // var_dump($field->flags & MYSQLI_ENUM_FLAG); die(); }*/ /* MYSQLI_BINARY_FLAG MYSQLI_BLOB_FLAG MYSQLI_ENUM_FLAG MYSQLI_MULTIPLE_KEY_FLAG MYSQLI_GROUP_FLAG MYSQLI_SET_FLAG MYSQLI_UNIQUE_KEY_FLAG MYSQLI_ZEROFILL_FLAG */ $column->setAlias($field->name); $column->setTableAlias($field->table); $column->setCatalog($field->catalog); $column->setOrdinalPosition($idx + 1); $column->setDataType($datatype['type']); $column->setIsNullable(!($field->flags & MYSQLI_NOT_NULL_FLAG) > 0 && $field->orgtable != ''); $column->setIsPrimary(($field->flags & MYSQLI_PRI_KEY_FLAG) > 0); $column->setColumnDefault($field->def); if (($field->flags & MYSQLI_SET_FLAG) > 0) { $column->setNativeDataType('SET'); } elseif (($field->flags & MYSQLI_ENUM_FLAG) > 0) { $column->setNativeDataType('ENUM'); } else { $column->setNativeDataType($datatype['native']); } if ($field->table == '') { $column->setIsGroup(($field->flags & MYSQLI_GROUP_FLAG) > 0); } if ($column instanceof Column\Definition\NumericColumnInterface) { $column->setNumericUnsigned(($field->flags & MYSQLI_UNSIGNED_FLAG) > 0); } if ($column instanceof Column\Definition\IntegerColumn) { $column->setIsAutoIncrement(($field->flags & MYSQLI_AUTO_INCREMENT_FLAG) > 0); } if ($column instanceof Column\Definition\DecimalColumn) { // salary DECIMAL(5,2) // In this example, 5 is the precision and 2 is the scale. // Standard SQL requires that DECIMAL(5,2) be able to store any value // with five digits and two decimals, so values that can be stored in // the salary column range from -999.99 to 999.99. $column->setNumericScale($field->length - $field->decimals + 1); $column->setNumericPrecision($field->decimals); } if ($column instanceof Column\Definition\StringColumn) { $column->setCharacterMaximumLength($field->length); } if ($column instanceof Column\Definition\BlobColumn) { $column->setCharacterOctetLength($field->length); } $alias = $column->getAlias(); if ($metadata->offsetExists($alias)) { $prev_column = $metadata->offsetGet($alias); $prev_def = $prev_column->toArray(); $curr_def = $column->toArray(); if ($prev_def['dataType'] != $curr_def['dataType'] || $prev_def['nativeDataType'] != $curr_def['nativeDataType']) { throw new Exception\AmbiguousColumnException("Cannot get column metadata, non unique column found '{$alias}' in query with different definitions."); } // If the the previous definition, was a prev_def if ($prev_def['isPrimary']) { $column = $prev_column; } } $metadata->offsetSet($alias, $column); } return $metadata; }
/** * * @param string $sql * @return \ArrayObject * @throws UnsupportedDatatypeException * @throws Exception\AmbiguousColumnException * @throws Exception\ConnectionException */ protected function readColumnsMetadata($sql) { $metadata = new ArrayObject(); $fields = $this->readFields($sql); $type_map = $this->getDatatypeMapping(); foreach ($fields as $idx => $field) { $name = $field['name']; $tableName = $field['table']; $datatype = strtoupper($field['native_type']); //@codeCoverageIgnoreStart if (!$type_map->offsetExists($datatype)) { throw new UnsupportedDatatypeException("Datatype '{$datatype}' not yet supported by " . __CLASS__); } //@codeCoverageIgnoreEnd $datatype = $type_map->offsetGet($datatype); $column = Column\Type::createColumnDefinition($datatype['type'], $name, $tableName, $schemaName = null); $alias = $field['name']; $column->setAlias($alias); $column->setTableAlias($field['table']); //$column->setCatalog($field->catalog); $column->setOrdinalPosition($idx + 1); $column->setDataType($datatype['type']); $column->setIsNullable(!in_array('not_null', $field['flags'])); $column->setIsPrimary(in_array('primary_key', $field['flags'])); //$column->setColumnDefault($field->def); $column->setNativeDataType($datatype['native']); /* if ($column instanceof Column\Definition\NumericColumnInterface) { $column->setNumericUnsigned(($field->flags & MYSQLI_UNSIGNED_FLAG) > 0); } if ($column instanceof Column\Definition\IntegerColumn) { $column->setIsAutoIncrement(($field->flags & MYSQLI_AUTO_INCREMENT_FLAG) > 0); } */ if ($column instanceof Column\Definition\DecimalColumn) { // salary DECIMAL(5,2) // In this example, 5 is the precision and 2 is the scale. // Standard SQL requires that DECIMAL(5,2) be able to store any value // with five digits and two decimals, so values that can be stored in // the salary column range from -999.99 to 999.99. $column->setNumericUnsigned(false); $column->setNumericPrecision($field['precision']); $column->setNumericScale($field['len'] - $field['precision'] + 1); } if ($column instanceof Column\Definition\StringColumn) { $column->setCharacterMaximumLength($field['len']); } if ($column instanceof Column\Definition\BlobColumn) { $column->setCharacterOctetLength($field['len']); } if ($metadata->offsetExists($alias)) { $prev_column = $metadata->offsetGet($alias); $prev_def = $prev_column->toArray(); $curr_def = $column->toArray(); if ($prev_def['dataType'] != $curr_def['dataType'] || $prev_def['nativeDataType'] != $curr_def['nativeDataType']) { throw new Exception\AmbiguousColumnException("Cannot get column metadata, non unique column found '{$alias}' in query with different definitions."); } // If the the previous definition, was a prev_def if ($prev_def['isPrimary']) { $column = $prev_column; } } $metadata->offsetSet($alias, $column); } return $metadata; }