Browse Source

...

tags/2.0.0-beta
Qiang Xue 13 years ago
parent
commit
cdfcc5d3f2
  1. 8
      framework/base/Model.php
  2. 17
      framework/db/dao/ColumnSchema.php
  3. 5
      framework/db/dao/DataReader.php
  4. 96
      framework/db/dao/Query.php
  5. 47
      framework/db/dao/QueryBuilder.php
  6. 59
      framework/db/dao/Schema.php
  7. 7
      framework/db/dao/TableSchema.php
  8. 4
      framework/db/dao/Transaction.php
  9. 2
      framework/db/dao/mysql/ColumnSchema.php

8
framework/base/Model.php

@ -281,7 +281,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
*/ */
public function onInit($event) public function onInit($event)
{ {
$this->raiseEvent(__METHOD__, $event); $this->raiseEvent(__FUNCTION__, $event);
} }
/** /**
@ -290,7 +290,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
*/ */
public function onAfterConstruct($event) public function onAfterConstruct($event)
{ {
$this->raiseEvent(__METHOD__, $event); $this->raiseEvent(__FUNCTION__, $event);
} }
/** /**
@ -299,7 +299,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
*/ */
public function onBeforeValidate($event) public function onBeforeValidate($event)
{ {
$this->raiseEvent(__METHOD__, $event); $this->raiseEvent(__FUNCTION__, $event);
} }
/** /**
@ -308,7 +308,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
*/ */
public function onAfterValidate($event) public function onAfterValidate($event)
{ {
$this->raiseEvent(__METHOD__, $event); $this->raiseEvent(__FUNCTION__, $event);
} }
/** /**

17
framework/db/dao/ColumnSchema.php

@ -11,7 +11,7 @@
namespace yii\db\dao; namespace yii\db\dao;
/** /**
* ColumnSchema class describes the column meta data of a database table. * ColumnSchema class describes the meta data of a column in a database table.
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
@ -23,7 +23,7 @@ class ColumnSchema extends \yii\base\Component
*/ */
public $name; public $name;
/** /**
* @var string raw name of this column. This is the quoted name that can be directly used in SQL queries. * @var string the quoted name of this column.
*/ */
public $quotedName; public $quotedName;
/** /**
@ -42,7 +42,7 @@ class ColumnSchema extends \yii\base\Component
*/ */
public $phpType; public $phpType;
/** /**
* @var string the DB type of this column. Possible DB types vary according to the DBMS. * @var string the DB type of this column. Possible DB types vary according to the type of DBMS.
*/ */
public $dbType; public $dbType;
/** /**
@ -50,11 +50,11 @@ class ColumnSchema extends \yii\base\Component
*/ */
public $defaultValue; public $defaultValue;
/** /**
* @var array enumerable values * @var array enumerable values. This is set only if the column is declared to be an enumerable type.
*/ */
public $enumValues; public $enumValues;
/** /**
* @var integer size of the column. * @var integer display size of the column.
*/ */
public $size; public $size;
/** /**
@ -75,7 +75,7 @@ class ColumnSchema extends \yii\base\Component
public $autoIncrement = false; public $autoIncrement = false;
/** /**
* @var boolean whether this column is unsigned. This is only meaningful * @var boolean whether this column is unsigned. This is only meaningful
* when [[type]] is `integer` or `bigint`. * when [[type]] is `smallint`, `integer` or `bigint`.
*/ */
public $unsigned; public $unsigned;
@ -83,7 +83,7 @@ class ColumnSchema extends \yii\base\Component
* Extracts the PHP type from DB type. * Extracts the PHP type from DB type.
* @return string PHP type name. * @return string PHP type name.
*/ */
protected function getPhpType() protected function extractPhpType()
{ {
static $typeMap = array( // logical type => php type static $typeMap = array( // logical type => php type
'smallint' => 'integer', 'smallint' => 'integer',
@ -104,7 +104,8 @@ class ColumnSchema extends \yii\base\Component
} }
/** /**
* Converts the input value to the type that this column is of. * Converts the input value according to [[phpType]].
* If the value is null or an [[Expression]], it will not be converted.
* @param mixed $value input value * @param mixed $value input value
* @return mixed converted value * @return mixed converted value
*/ */

5
framework/db/dao/DataReader.php

@ -32,6 +32,11 @@ use yii\db\Exception;
* [[fetchMode]]. See the [PHP manual](http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php) * [[fetchMode]]. See the [PHP manual](http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php)
* for more details about possible fetch mode. * for more details about possible fetch mode.
* *
* @property boolean $isClosed whether the reader is closed or not.
* @property integer $rowCount number of rows contained in the result.
* @property integer $columnCount the number of columns in the result set.
* @property mixed $fetchMode fetch mode used when retrieving the data.
*
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */

96
framework/db/dao/Query.php

@ -34,6 +34,8 @@ namespace yii\db\dao;
* And by calling [[createCommand()]], we can get a [[Command]] instance which can be further * And by calling [[createCommand()]], we can get a [[Command]] instance which can be further
* used to perform/execute the DB query against a database. * used to perform/execute the DB query against a database.
* *
* @property string $sql the SQL statement represented by this query object.
*
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
@ -512,6 +514,38 @@ class Query extends \yii\base\Object
} }
/** /**
* Sets the parameters to be bound to the query.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* @return Query the query object itself
* @see addParams()
*/
public function params($params)
{
$this->params = $params;
return $this;
}
/**
* Adds additional parameters to be bound to the query.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* @return Query the query object itself
* @see params()
*/
public function addParams($params)
{
foreach ($params as $name => $value) {
if (is_integer($name)) {
$this->params[] = $value;
} else {
$this->params[$name] = $value;
}
}
return $this;
}
/**
* Creates and executes an INSERT SQL statement. * Creates and executes an INSERT SQL statement.
* The method will properly escape the column names, and bind the values to be inserted. * The method will properly escape the column names, and bind the values to be inserted.
* @param string $table the table that new rows will be inserted into. * @param string $table the table that new rows will be inserted into.
@ -520,7 +554,7 @@ class Query extends \yii\base\Object
*/ */
public function insert($table, $columns) public function insert($table, $columns)
{ {
$this->operation = array('insert', $table, $columns, array()); $this->operation = array(__FUNCTION__, $table, $columns, array());
return $this; return $this;
} }
@ -537,7 +571,7 @@ class Query extends \yii\base\Object
public function update($table, $columns, $condition = '', $params = array()) public function update($table, $columns, $condition = '', $params = array())
{ {
$this->addParams($params); $this->addParams($params);
$this->operation = array('update', $table, $columns, $condition, array()); $this->operation = array(__FUNCTION__, $table, $columns, $condition, array());
return $this; return $this;
} }
@ -551,7 +585,7 @@ class Query extends \yii\base\Object
*/ */
public function delete($table, $condition = '', $params = array()) public function delete($table, $condition = '', $params = array())
{ {
$this->operation = array('delete', $table, $condition); $this->operation = array(__FUNCTION__, $table, $condition);
return $this->addParams($params); return $this->addParams($params);
} }
@ -575,7 +609,7 @@ class Query extends \yii\base\Object
*/ */
public function createTable($table, $columns, $options = null) public function createTable($table, $columns, $options = null)
{ {
$this->operation = array('createTable', $table, $columns, $options); $this->operation = array(__FUNCTION__, $table, $columns, $options);
return $this; return $this;
} }
@ -587,7 +621,7 @@ class Query extends \yii\base\Object
*/ */
public function renameTable($table, $newName) public function renameTable($table, $newName)
{ {
$this->operation = array('renameTable', $table, $newName); $this->operation = array(__FUNCTION__, $table, $newName);
return $this; return $this;
} }
@ -598,7 +632,7 @@ class Query extends \yii\base\Object
*/ */
public function dropTable($table) public function dropTable($table)
{ {
$this->operation = array('dropTable', $table); $this->operation = array(__FUNCTION__, $table);
return $this; return $this;
} }
@ -609,7 +643,7 @@ class Query extends \yii\base\Object
*/ */
public function truncateTable($table) public function truncateTable($table)
{ {
$this->operation = array('truncateTable', $table); $this->operation = array(__FUNCTION__, $table);
return $this; return $this;
} }
@ -624,7 +658,7 @@ class Query extends \yii\base\Object
*/ */
public function addColumn($table, $column, $type) public function addColumn($table, $column, $type)
{ {
$this->operation = array('addColumn', $table, $column, $type); $this->operation = array(__FUNCTION__, $table, $column, $type);
return $this; return $this;
} }
@ -636,7 +670,7 @@ class Query extends \yii\base\Object
*/ */
public function dropColumn($table, $column) public function dropColumn($table, $column)
{ {
$this->operation = array('dropColumn', $table, $column); $this->operation = array(__FUNCTION__, $table, $column);
return $this; return $this;
} }
@ -649,7 +683,7 @@ class Query extends \yii\base\Object
*/ */
public function renameColumn($table, $name, $newName) public function renameColumn($table, $name, $newName)
{ {
$this->operation = array('renameColumn', $table, $name, $newName); $this->operation = array(__FUNCTION__, $table, $name, $newName);
return $this; return $this;
} }
@ -664,7 +698,7 @@ class Query extends \yii\base\Object
*/ */
public function alterColumn($table, $column, $type) public function alterColumn($table, $column, $type)
{ {
$this->operation = array('alterColumn', $table, $column, $type); $this->operation = array(__FUNCTION__, $table, $column, $type);
return $this; return $this;
} }
@ -682,7 +716,7 @@ class Query extends \yii\base\Object
*/ */
public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null) public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null)
{ {
$this->operation = array('addForeignKey', $name, $table, $columns, $refTable, $refColumns, $delete, $update); $this->operation = array(__FUNCTION__, $name, $table, $columns, $refTable, $refColumns, $delete, $update);
return $this; return $this;
} }
@ -694,7 +728,7 @@ class Query extends \yii\base\Object
*/ */
public function dropForeignKey($name, $table) public function dropForeignKey($name, $table)
{ {
$this->operation = array('dropForeignKey', $name, $table); $this->operation = array(__FUNCTION__, $name, $table);
return $this; return $this;
} }
@ -709,7 +743,7 @@ class Query extends \yii\base\Object
*/ */
public function createIndex($name, $table, $columns, $unique = false) public function createIndex($name, $table, $columns, $unique = false)
{ {
$this->operation = array('createIndex', $name, $table, $columns, $unique); $this->operation = array(__FUNCTION__, $name, $table, $columns, $unique);
return $this; return $this;
} }
@ -721,39 +755,7 @@ class Query extends \yii\base\Object
*/ */
public function dropIndex($name, $table) public function dropIndex($name, $table)
{ {
$this->operation = array('dropIndex', $name, $table); $this->operation = array(__FUNCTION__, $name, $table);
return $this;
}
/**
* Sets the parameters to be bound to the query.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* @return Query the query object itself
* @see addParams()
*/
public function params($params)
{
$this->params = $params;
return $this;
}
/**
* Adds additional parameters to be bound to the query.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* @return Query the query object itself
* @see params()
*/
public function addParams($params)
{
foreach ($params as $name => $value) {
if (is_integer($name)) {
$this->params[] = $value;
} else {
$this->params[$name] = $value;
}
}
return $this; return $this;
} }

47
framework/db/dao/QueryBuilder.php

@ -34,6 +34,11 @@ class QueryBuilder extends \yii\base\Object
*/ */
public $schema; public $schema;
/** /**
* @var string the separator between different fragments of a SQL statement.
* Defaults to an empty space. This is mainly used by [[build()]] when generating a SQL statement.
*/
public $separator = " ";
/**
* @var Query the Query object. This is set when calling [[build()]] to generate a non-SELECT SQL statement. * @var Query the Query object. This is set when calling [[build()]] to generate a non-SELECT SQL statement.
*/ */
private $_query; private $_query;
@ -49,32 +54,36 @@ class QueryBuilder extends \yii\base\Object
} }
/** /**
* @param Query $query * Generates a SQL statement from a [[Query]] object.
* @return string * Note that when generating SQL statements for INSERT and UPDATE queries,
* the query object's [[Query::params]] property may be appended with new parameters.
* @param Query $query the [[Query]] object from which the SQL statement will be generated
* @return string the generated SQL statement
*/ */
public function build($query) public function build($query)
{ {
// non-SELECT query
if ($query->operation !== null) { if ($query->operation !== null) {
// non-SELECT query
$this->_query = $query; $this->_query = $query;
$method = array_shift($query->operation); $method = array_shift($query->operation);
$sql = call_user_func_array(array($this, $method), $query->operation); $sql = call_user_func_array(array($this, $method), $query->operation);
$this->_query = null; $this->_query = null;
return $sql; return $sql;
} else {
// SELECT query
$clauses = array(
$this->buildSelect($query),
$this->buildFrom($query),
$this->buildJoin($query),
$this->buildWhere($query),
$this->buildGroupBy($query),
$this->buildHaving($query),
$this->buildUnion($query),
$this->buildOrderBy($query),
$this->buildLimit($query),
);
return implode($this->separator, array_filter($clauses));
} }
// SELECT query
$clauses = array(
$this->buildSelect($query),
$this->buildFrom($query),
$this->buildJoin($query),
$this->buildWhere($query),
$this->buildGroupBy($query),
$this->buildHaving($query),
$this->buildUnion($query),
$this->buildOrderBy($query),
$this->buildLimit($query),
);
return implode("\n", array_filter($clauses));
} }
/** /**
@ -82,7 +91,8 @@ class QueryBuilder extends \yii\base\Object
* The method will properly escape the column names, and bind the values to be inserted. * The method will properly escape the column names, and bind the values to be inserted.
* @param string $table the table that new rows will be inserted into. * @param string $table the table that new rows will be inserted into.
* @param array $columns the column data (name=>value) to be inserted into the table. * @param array $columns the column data (name=>value) to be inserted into the table.
* @param array $params the parameters to be bound to the query. * @param array $params the parameters to be bound to the query. This method will modify
* this parameter by appending new parameters to be bound to the query.
* @return integer number of rows affected by the execution. * @return integer number of rows affected by the execution.
*/ */
public function insert($table, $columns, &$params = array()) public function insert($table, $columns, &$params = array())
@ -119,7 +129,8 @@ class QueryBuilder extends \yii\base\Object
* @param array $columns the column data (name=>value) to be updated. * @param array $columns the column data (name=>value) to be updated.
* @param mixed $condition the condition that will be put in the WHERE part. Please * @param mixed $condition the condition that will be put in the WHERE part. Please
* refer to [[Query::where()]] on how to specify condition. * refer to [[Query::where()]] on how to specify condition.
* @param array $params the parameters to be bound to the query. * @param array $params the parameters to be bound to the query. This method will modify
* this parameter by appending new parameters to be bound to the query.
* @return integer number of rows affected by the execution. * @return integer number of rows affected by the execution.
*/ */
public function update($table, $columns, $condition = '', &$params = array()) public function update($table, $columns, $condition = '', &$params = array())

59
framework/db/dao/Schema.php

@ -13,7 +13,13 @@ namespace yii\db\dao;
use yii\db\Exception; use yii\db\Exception;
/** /**
* Schema is the base class for retrieving metadata information. * Schema represents the meta data of a database.
*
* Schema retrieves and maintains the meta data of database tables and columns.
*
* @property QueryBuilder $queryBuilder the query builder for this connection.
* @property array $tableNames the names of all tables in this database.
* @property array $tableSchemas the meta data for all tables in this database.
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
@ -37,18 +43,26 @@ abstract class Schema extends \yii\base\Object
const TYPE_MONEY = 'money'; const TYPE_MONEY = 'money';
/** /**
* @var \yii\db\dao\Connection the database connection * @var Connection the database connection
*/ */
public $connection; public $connection;
/**
* @var array list of ALL table names in the database
*/
private $_tableNames = array(); private $_tableNames = array();
/**
* @var array list of loaded table meta data (table name => TableSchema)
*/
private $_tables = array(); private $_tables = array();
/**
* @var QueryBuilder the query builder for this database
*/
private $_builder; private $_builder;
/** /**
* Loads the metadata for the specified table. * Loads the metadata for the specified table.
* @param string $name table name * @param string $name table name
* @return TableSchema driver dependent table metadata, null if the table does not exist. * @return TableSchema DBMS-dependent table metadata, null if the table does not exist.
*/ */
abstract protected function loadTableSchema($name); abstract protected function loadTableSchema($name);
@ -64,31 +78,28 @@ abstract class Schema extends \yii\base\Object
/** /**
* Obtains the metadata for the named table. * Obtains the metadata for the named table.
* @param string $name table name. The table name may contain schema name if any. Do not quote the table name. * @param string $name table name. The table name may contain schema name if any. Do not quote the table name.
* @param boolean $refresh whether to reload the table schema even if it is found in the cache.
* @return TableSchema table metadata. Null if the named table does not exist. * @return TableSchema table metadata. Null if the named table does not exist.
*/ */
public function getTableSchema($name) public function getTableSchema($name, $refresh = false)
{ {
if (isset($this->_tables[$name])) { if (isset($this->_tables[$name]) && !$refresh) {
return $this->_tables[$name]; return $this->_tables[$name];
} }
if (strpos($name, '{{') !== false) {
$realName = preg_replace('/\{\{(.*?)\}\}/', $this->connection->tablePrefix . '$1', $name);
} else {
$realName = $name;
}
$db = $this->connection; $db = $this->connection;
$realName = $db->expandTablePrefix($name);
// temporarily disable query caching // temporarily disable query caching
if ($db->queryCachingDuration >= 0) { if ($db->queryCachingDuration >= 0) {
$qcDuration = $db->queryCachingDuration; $qcDuration = $db->queryCachingDuration;
$db->queryCachingDuration = -1; $db->queryCachingDuration = -1;
} }
if (!in_array($name, $db->schemaCachingExclude) && $db->schemaCachingDuration >= 0 && ($cache = \Yii::$application->getComponent($db->schemaCacheID)) !== null) { if (!in_array($name, $db->schemaCachingExclude, true) && $db->schemaCachingDuration >= 0 && ($cache = \Yii::$application->getComponent($db->schemaCacheID)) !== null) {
$key = __CLASS__ . "/{$db->dsn}/{$db->username}/{$name}"; $key = $this->getCacheKey($name);
if (($table = $cache->get($key)) === false) { if ($refresh || ($table = $cache->get($key)) === false) {
$table = $this->loadTableSchema($realName); $table = $this->loadTableSchema($realName);
if ($table !== null) { if ($table !== null) {
$cache->set($key, $table, $db->schemaCachingDuration); $cache->set($key, $table, $db->schemaCachingDuration);
@ -107,10 +118,20 @@ abstract class Schema extends \yii\base\Object
} }
/** /**
* Returns the cache key for the specified table name.
* @param string $name the table name
* @return string the cache key
*/
public function getCacheKey($name)
{
return __CLASS__ . "/{$this->connection->dsn}/{$this->connection->username}/{$name}";
}
/**
* Returns the metadata for all tables in the database. * Returns the metadata for all tables in the database.
* @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema. * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema.
* @return array the metadata for all tables in the database. * @return array the metadata for all tables in the database.
* Each array element is an instance of {@link CDbTableSchema} (or its child class). * Each array element is an instance of [[TableSchema]] (or its child class).
*/ */
public function getTableSchemas($schema = '') public function getTableSchemas($schema = '')
{ {
@ -158,8 +179,7 @@ abstract class Schema extends \yii\base\Object
$db = $this->connection; $db = $this->connection;
if ($db->schemaCachingDuration >= 0 && ($cache = \Yii::$application->getComponent($db->schemaCacheID)) !== null) { if ($db->schemaCachingDuration >= 0 && ($cache = \Yii::$application->getComponent($db->schemaCacheID)) !== null) {
foreach ($this->_tables as $name => $table) { foreach ($this->_tables as $name => $table) {
$key = __CLASS__ . ":{$db->dsn}/{$db->username}/{$name}"; $cache->delete($this->getCacheKey($name));
$cache->delete($key);
} }
} }
$this->_tables = array(); $this->_tables = array();
@ -209,8 +229,7 @@ abstract class Schema extends \yii\base\Object
if (($pos = strrpos($name, '.')) !== false) { if (($pos = strrpos($name, '.')) !== false) {
$prefix = $this->quoteTableName(substr($name, 0, $pos)) . '.'; $prefix = $this->quoteTableName(substr($name, 0, $pos)) . '.';
$name = substr($name, $pos + 1); $name = substr($name, $pos + 1);
} else } else {
{
$prefix = ''; $prefix = '';
} }
return $prefix . $this->quoteSimpleColumnName($name); return $prefix . $this->quoteSimpleColumnName($name);

7
framework/db/dao/TableSchema.php

@ -13,7 +13,9 @@ namespace yii\db\dao;
/** /**
* TableSchema is the base class for representing the metadata of a database table. * TableSchema is the base class for representing the metadata of a database table.
* *
* It may be extended by different DBMS driver to provide DBMS-specific table metadata. * It may be extended by different DBMS driver to represent DBMS-specific table metadata.
*
* @property array $columnNames list of column names
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
@ -61,7 +63,7 @@ class TableSchema extends \yii\base\Object
* Gets the named column metadata. * Gets the named column metadata.
* This is a convenient method for retrieving a named column even if it does not exist. * This is a convenient method for retrieving a named column even if it does not exist.
* @param string $name column name * @param string $name column name
* @return CDbColumnSchema metadata of the named column. Null if the named column does not exist. * @return ColumnSchema metadata of the named column. Null if the named column does not exist.
*/ */
public function getColumn($name) public function getColumn($name)
{ {
@ -69,6 +71,7 @@ class TableSchema extends \yii\base\Object
} }
/** /**
* Returns the names of all columns in this table.
* @return array list of column names * @return array list of column names
*/ */
public function getColumnNames() public function getColumnNames()

4
framework/db/dao/Transaction.php

@ -15,7 +15,7 @@ use yii\db\Exception;
/** /**
* Transaction represents a DB transaction. * Transaction represents a DB transaction.
* *
* It is usually created by calling [[Connection::beginTransaction]]. * It is usually created by calling [[Connection::beginTransaction()]].
* *
* The following code is a typical example of using transactions (note that some * The following code is a typical example of using transactions (note that some
* DBMS may not support transactions): * DBMS may not support transactions):
@ -39,7 +39,7 @@ class Transaction extends \yii\base\Object
{ {
/** /**
* @var boolean whether this transaction is active. Only an active transaction * @var boolean whether this transaction is active. Only an active transaction
* can [[commit]] or [[rollBack]]. This property is set true when the transaction is started. * can [[commit()]] or [[rollBack()]]. This property is set true when the transaction is started.
*/ */
public $active; public $active;
/** /**

2
framework/db/dao/mysql/ColumnSchema.php

@ -88,7 +88,7 @@ class ColumnSchema extends \yii\db\dao\ColumnSchema
} }
} }
$this->phpType = $this->getPhpType(); $this->phpType = $this->extractPhpType();
} }
/** /**

Loading…
Cancel
Save