diff --git a/Columna.php b/Columna.php index 4e17688..6f3b3e7 100644 --- a/Columna.php +++ b/Columna.php @@ -20,6 +20,9 @@ final class Columna /** @var string */ public $nombre = ''; + /** bool */ + public $primary = false; + /** bool */ public $requerido = false; @@ -55,8 +58,8 @@ public function ask(array $previous): void if ($type === 1) { foreach ($previous as $column) { - if ($column->tipo === 'serial') { - echo "\nYa hay un campo de tipo serial.\n"; + if ($column->tipo === 'serial' || $column->primary) { + echo "\nYa hay un campo de tipo serial o primary key.\n"; continue 2; } } @@ -104,6 +107,8 @@ private function setType(int $type): void switch ($type) { case 1: $this->tipo = 'serial'; + $this->primary = true; + $this->requerido = true; return; case 2: diff --git a/fsmaker.php b/fsmaker.php index 13f7796..3fee4f0 100644 --- a/fsmaker.php +++ b/fsmaker.php @@ -85,6 +85,7 @@ private function askFields(): array $fields[] = new Columna([ 'display' => 'none', 'nombre' => 'id', + 'primary' => true, 'requerido' => true, 'tipo' => 'serial' ]); @@ -120,9 +121,11 @@ private function askFields(): array echo "\n"; while (true) { - $name = strtolower($this->prompt('Nombre del campo (vacío para terminar)')); - if (empty($name)) { + $name = $this->prompt('Nombre del campo (vacío para terminar)', '/^[a-z][a-z0-9_]*$/'); + if (is_null($name)) { break; + } elseif (empty($name)) { + continue; } if (in_array($name, explode(',', self::FORBIDDEN_WORDS))) { @@ -142,9 +145,36 @@ private function askFields(): array return strcmp($a->nombre, $b->nombre); }); + $this->askPrimaryKey($fields); return $fields; } + private function askPrimaryKey(array &$fields) + { + // si hay un campo serial o primary key, terminamos + foreach ($fields as $field) { + if ($field->tipo === 'serial' || $field->primary) { + return; + } + } + + // indicamos que campo es la clave primaria + while (true) { + foreach ($fields as $index => $field) { + echo $index . " - " . $field->nombre . "\n"; + } + + $pos = $this->prompt('No estableció ninguna clave primaria, seleccione una de las anteriores', '/^[0-9]*$/'); + if ($pos == '' || false === isset($fields[$pos])) { + continue; + } + + $fields[$pos]->primary = true; + $fields[$pos]->requerido = true; + break; + } + } + private function createController() { $name = $this->prompt('Nombre del controlador', '/^[A-Z][a-zA-Z0-9_]*$/'); @@ -611,6 +641,10 @@ private function createModelByFields(string $fileName, string $tableName, array break; } + if ($field->primary) { + $primaryColumn = $field->nombre; + } + if (strpos($field->tipo, 'character varying') !== false) { $typeProperty = 'string'; if (false === in_array($field->nombre, $testExclude)) { @@ -765,13 +799,13 @@ private function createXMLTableByFields(string $tableFilename, string $tableName . " $field->nombre\n" . " $field->tipo\n"; - if ($field->tipo === 'serial' || $field->requerido) { + if ($field->tipo === 'serial' || $field->primary || $field->requerido) { $columns .= " NO\n"; } $columns .= " \n"; - if ($field->tipo === 'serial') { + if ($field->tipo === 'serial' || $field->primary) { $constraints .= " \n" . ' ' . $tableName . "_pkey\n" . ' PRIMARY KEY (' . $field->nombre . ")\n" @@ -822,8 +856,8 @@ private function createXMLViewByFields(string $xmlFilename, array $fields, int $ continue; } - // si la columna es de tipo serial, la ponemos al principio - if ($field->tipo === 'serial') { + // si la columna es de tipo serial o primary, la ponemos al principio + if ($field->tipo === 'serial' || $field->primary) { $columns = $this->getWidget($field, $order, $tabForColums) . $columns; $order += 10; continue; @@ -1042,11 +1076,17 @@ private function modifyInit(string $name, int $modelOrController) echo '* ' . $fileName . self::OK; } - private function prompt($label, $pattern = ''): string + private function prompt($label, $pattern = ''): ?string { echo $label . ': '; $matches = []; $value = trim(fgets(STDIN)); + + // si el valor esta vacío, devolvemos null + if ($value == '') { + return null; + } + if (!empty($pattern) && 1 !== preg_match($pattern, $value, $matches)) { echo "Valor no válido. Debe cumplir: " . $pattern . "\n"; return '';