mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-16 06:17:56 +08:00
model generator WIP
This commit is contained in:
@@ -497,14 +497,15 @@ class Connection extends Component
|
|||||||
* Processes a SQL statement by quoting table and column names that are enclosed within double brackets.
|
* Processes a SQL statement by quoting table and column names that are enclosed within double brackets.
|
||||||
* Tokens enclosed within double curly brackets are treated as table names, while
|
* Tokens enclosed within double curly brackets are treated as table names, while
|
||||||
* tokens enclosed within double square brackets are column names. They will be quoted accordingly.
|
* tokens enclosed within double square brackets are column names. They will be quoted accordingly.
|
||||||
* Also, the percentage character "%" in a table name will be replaced with [[tablePrefix]].
|
* Also, the percentage character "%" at the beginning or ending of a table name will be replaced
|
||||||
|
* with [[tablePrefix]].
|
||||||
* @param string $sql the SQL to be quoted
|
* @param string $sql the SQL to be quoted
|
||||||
* @return string the quoted SQL
|
* @return string the quoted SQL
|
||||||
*/
|
*/
|
||||||
public function quoteSql($sql)
|
public function quoteSql($sql)
|
||||||
{
|
{
|
||||||
$db = $this;
|
$db = $this;
|
||||||
return preg_replace_callback('/(\\{\\{([%\w\-\. ]+)\\}\\}|\\[\\[([\w\-\. ]+)\\]\\])/',
|
return preg_replace_callback('/(\\{\\{(%?[\w\-\. ]+)\\}\\}|\\{\\{([\w\-\. ]+%?)\\}\\}|\\[\\[([\w\-\. ]+)\\]\\])/',
|
||||||
function ($matches) use ($db) {
|
function ($matches) use ($db) {
|
||||||
if (isset($matches[3])) {
|
if (isset($matches[3])) {
|
||||||
return $db->quoteColumnName($matches[3]);
|
return $db->quoteColumnName($matches[3]);
|
||||||
|
|||||||
@@ -302,16 +302,19 @@ abstract class Generator extends Model
|
|||||||
*/
|
*/
|
||||||
public function validateClass($attribute, $params)
|
public function validateClass($attribute, $params)
|
||||||
{
|
{
|
||||||
|
$class = $this->$attribute;
|
||||||
try {
|
try {
|
||||||
if (class_exists($this->$attribute)) {
|
if (class_exists($class)) {
|
||||||
if (isset($params['extends']) && !is_subclass_of($this->$attribute, $params['extends'])) {
|
if (isset($params['extends'])) {
|
||||||
$this->addError($attribute, "'{$this->$attribute}' must extend from {$params['extends']} or its child class.");
|
if (ltrim($class, '\\') !== ltrim($params['extends'], '\\') && !is_subclass_of($class, $params['extends'])) {
|
||||||
|
$this->addError($attribute, "'$class' must extend from {$params['extends']} or its child class.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->addError($attribute, "Class '{$this->$attribute}' does not exist or has syntax error.");
|
$this->addError($attribute, "Class '$class' does not exist or has syntax error.");
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->addError($attribute, "Class '{$this->$attribute}' does not exist or has syntax error.");
|
$this->addError($attribute, "Class '$class' does not exist or has syntax error.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class Generator extends \yii\gii\Generator
|
|||||||
public $ns = 'app\models';
|
public $ns = 'app\models';
|
||||||
public $tableName;
|
public $tableName;
|
||||||
public $modelClass;
|
public $modelClass;
|
||||||
public $baseClass = '\yii\db\ActiveRecord';
|
public $baseClass = 'yii\db\ActiveRecord';
|
||||||
public $generateRelations = true;
|
public $generateRelations = true;
|
||||||
public $generateLabelsFromComments = false;
|
public $generateLabelsFromComments = false;
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ class Generator extends \yii\gii\Generator
|
|||||||
array('db, ns, tableName, baseClass', 'required'),
|
array('db, ns, tableName, baseClass', 'required'),
|
||||||
array('db, modelClass', 'match', 'pattern' => '/^\w+$/', 'message' => 'Only word characters are allowed.'),
|
array('db, modelClass', 'match', 'pattern' => '/^\w+$/', 'message' => 'Only word characters are allowed.'),
|
||||||
array('ns, baseClass', 'match', 'pattern' => '/^[\w\\\\]+$/', 'message' => 'Only word characters and backslashes are allowed.'),
|
array('ns, baseClass', 'match', 'pattern' => '/^[\w\\\\]+$/', 'message' => 'Only word characters and backslashes are allowed.'),
|
||||||
array('tableName', 'match', 'pattern' => '/^(\w+\.)?\w+\*?$/', 'message' => 'Only word characters, and optionally an asterisk and/or a dot are allowed.'),
|
array('tableName', 'match', 'pattern' => '/^(\w+\.)?([\w\*]+)$/', 'message' => 'Only word characters, and optionally an asterisk and/or a dot are allowed.'),
|
||||||
array('db', 'validateDb'),
|
array('db', 'validateDb'),
|
||||||
array('ns', 'validateNamespace'),
|
array('ns', 'validateNamespace'),
|
||||||
array('tableName', 'validateTableName'),
|
array('tableName', 'validateTableName'),
|
||||||
@@ -123,7 +123,7 @@ class Generator extends \yii\gii\Generator
|
|||||||
'labels' => $this->generateLabels($tableSchema),
|
'labels' => $this->generateLabels($tableSchema),
|
||||||
);
|
);
|
||||||
$files[] = new CodeFile(
|
$files[] = new CodeFile(
|
||||||
Yii::getAlias('@' . $this->ns) . '/' . $className . '.php',
|
Yii::getAlias('@' . str_replace('\\', '/', $this->ns)) . '/' . $className . '.php',
|
||||||
$this->render('model.php', $params)
|
$this->render('model.php', $params)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -142,6 +142,8 @@ class Generator extends \yii\gii\Generator
|
|||||||
foreach ($table->columns as $column) {
|
foreach ($table->columns as $column) {
|
||||||
if ($this->generateLabelsFromComments && !empty($column->comment)) {
|
if ($this->generateLabelsFromComments && !empty($column->comment)) {
|
||||||
$labels[$column->name] = $column->comment;
|
$labels[$column->name] = $column->comment;
|
||||||
|
} elseif (!strcasecmp($column->name, 'id')) {
|
||||||
|
$labels[$column->name] = 'ID';
|
||||||
} else {
|
} else {
|
||||||
$label = Inflector::camel2words($column->name);
|
$label = Inflector::camel2words($column->name);
|
||||||
if (strcasecmp(substr($label, -3), ' id') === 0) {
|
if (strcasecmp(substr($label, -3), ' id') === 0) {
|
||||||
@@ -317,22 +319,30 @@ class Generator extends \yii\gii\Generator
|
|||||||
|
|
||||||
protected function generateClassName($tableName)
|
protected function generateClassName($tableName)
|
||||||
{
|
{
|
||||||
if ($this->tableName === $tableName || ($pos = strrpos($this->tableName, '.')) !== false && substr($this->tableName, $pos + 1) === $tableName) {
|
if (($pos = strrpos($tableName, '.')) !== false) {
|
||||||
return $this->modelClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
$tableName = $this->removePrefix($tableName, false);
|
|
||||||
if (($pos = strpos($tableName, '.')) !== false) // remove schema part (e.g. remove 'public2.' from 'public2.post')
|
|
||||||
{
|
|
||||||
$tableName = substr($tableName, $pos + 1);
|
$tableName = substr($tableName, $pos + 1);
|
||||||
}
|
}
|
||||||
$className = '';
|
|
||||||
foreach (explode('_', $tableName) as $name) {
|
$db = $this->getDbConnection();
|
||||||
if ($name !== '') {
|
$patterns = array();
|
||||||
$className .= ucfirst($name);
|
if (strpos($this->tableName, '*') !== false) {
|
||||||
|
$pattern = $this->tableName;
|
||||||
|
if (($pos = strrpos($pattern, '.')) !== false) {
|
||||||
|
$pattern = substr($pattern, $pos + 1);
|
||||||
|
}
|
||||||
|
$patterns[] = '/^' . str_replace('*', '(\w+)', $pattern) . '$/';
|
||||||
|
}
|
||||||
|
if (!empty($db->tablePrefix)) {
|
||||||
|
$patterns[] = "/^{$db->tablePrefix}(.*?)|(.*?){$db->tablePrefix}$/";
|
||||||
|
}
|
||||||
|
|
||||||
|
$className = $tableName;
|
||||||
|
foreach ($patterns as $pattern) {
|
||||||
|
if (preg_match($pattern, $tableName, $matches)) {
|
||||||
|
$className = $matches[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $className;
|
return Inflector::id2camel($className, '_');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -375,14 +385,17 @@ class Generator extends \yii\gii\Generator
|
|||||||
|
|
||||||
public function validateDb()
|
public function validateDb()
|
||||||
{
|
{
|
||||||
if (Yii::$app->hasComponent($this->db) === false || !(Yii::$app->getComponent($this->db) instanceof Connection)) {
|
if (Yii::$app->hasComponent($this->db) === false) {
|
||||||
$this->addError('db', 'Database Connection ID must refer to a valid application component.');
|
$this->addError('db', 'There is no application component named "db".');
|
||||||
|
} elseif (!Yii::$app->getComponent($this->db) instanceof Connection) {
|
||||||
|
$this->addError('db', 'The "db" application component must be a DB connection instance.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validateNamespace()
|
public function validateNamespace()
|
||||||
{
|
{
|
||||||
$path = Yii::getAlias('@' . ltrim($this->ns, '\\'), false);
|
$this->ns = ltrim($this->ns, '\\');
|
||||||
|
$path = Yii::getAlias('@' . str_replace('\\', '/', $this->ns), false);
|
||||||
if ($path === false) {
|
if ($path === false) {
|
||||||
$this->addError('ns', 'Namespace must be associated with an existing directory.');
|
$this->addError('ns', 'Namespace must be associated with an existing directory.');
|
||||||
}
|
}
|
||||||
@@ -400,14 +413,18 @@ class Generator extends \yii\gii\Generator
|
|||||||
|
|
||||||
public function validateTableName()
|
public function validateTableName()
|
||||||
{
|
{
|
||||||
|
if (($pos = strpos($this->tableName, '*')) !== false && strpos($this->tableName, '*', $pos + 1) !== false) {
|
||||||
|
$this->addError('tableName', 'At most one asterisk is allowed.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
$tables = $this->getTableNames();
|
$tables = $this->getTableNames();
|
||||||
if (empty($tables)) {
|
if (empty($tables)) {
|
||||||
$this->addError('tableName', "Table '{$this->tableName}' does not exist.'");
|
$this->addError('tableName', "Table '{$this->tableName}' does not exist.");
|
||||||
} else {
|
} else {
|
||||||
foreach ($tables as $table) {
|
foreach ($tables as $table) {
|
||||||
$class = $this->generateClassName($table);
|
$class = $this->generateClassName($table);
|
||||||
if ($this->isReservedKeyword($class)) {
|
if ($this->isReservedKeyword($class)) {
|
||||||
$this->addError('tableName', "Table '$table' would generate a class which is a reserved PHP keyword.");
|
$this->addError('tableName', "Table '$table' will generate a class which is a reserved PHP keyword.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -418,13 +435,13 @@ class Generator extends \yii\gii\Generator
|
|||||||
{
|
{
|
||||||
$db = $this->getDbConnection();
|
$db = $this->getDbConnection();
|
||||||
$tableNames = array();
|
$tableNames = array();
|
||||||
if ($this->tableName[strlen($this->tableName) - 1] === '*') {
|
if (strpos($this->tableName, '*') !== false) {
|
||||||
if (($pos = strrpos($this->tableName, '.')) !== false) {
|
if (($pos = strrpos($this->tableName, '.')) !== false) {
|
||||||
$schema = substr($this->tableName, 0, $pos);
|
$schema = substr($this->tableName, 0, $pos);
|
||||||
$pattern = '/' . str_replace('*', '\w+', substr($this->tableName, $pos + 1)) . '/';
|
$pattern = '/^' . str_replace('*', '\w+', substr($this->tableName, $pos + 1)) . '$/';
|
||||||
} else {
|
} else {
|
||||||
$schema = '';
|
$schema = '';
|
||||||
$pattern = '/' . str_replace('*', '\w+', $this->tableName) . '/';
|
$pattern = '/^' . str_replace('*', '\w+', $this->tableName) . '$/';
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($db->schema->getTableNames($schema) as $table) {
|
foreach ($db->schema->getTableNames($schema) as $table) {
|
||||||
|
|||||||
@@ -17,14 +17,10 @@
|
|||||||
* - $relations: list of relations (name=>relation declaration)
|
* - $relations: list of relations (name=>relation declaration)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$pos = strrpos($className, '\\');
|
|
||||||
$ns = ltrim(substr($className, 0, $pos), '\\');
|
|
||||||
$className = substr($className, $pos + 1);
|
|
||||||
|
|
||||||
echo "<?php\n";
|
echo "<?php\n";
|
||||||
?>
|
?>
|
||||||
|
|
||||||
namespace <?php echo $ns; ?>;
|
namespace <?php echo $generator->ns; ?>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the model class for table "<?php echo $tableName; ?>".
|
* This is the model class for table "<?php echo $tableName; ?>".
|
||||||
|
|||||||
Reference in New Issue
Block a user