getConnection() ->getSchemaBuilder(); } protected function getModelTable(string $model): string { return app($model)->getTable(); } protected function guessBelongsToRelationshipName(string $column, string $model): ?string { /** @var Model $modelInstance */ $modelInstance = app($model); $modelInstanceReflection = new ReflectionClass($modelInstance); $guessedRelationshipName = str($column)->beforeLast('_id'); $hasRelationship = $modelInstanceReflection->hasMethod($guessedRelationshipName); if (! $hasRelationship) { $guessedRelationshipName = $guessedRelationshipName->camel(); $hasRelationship = $modelInstanceReflection->hasMethod($guessedRelationshipName); } if (! $hasRelationship) { return null; } try { $type = $modelInstanceReflection->getMethod($guessedRelationshipName)->getReturnType(); if ( (! $type) || (! method_exists($type, 'getName')) || ($type->getName() !== BelongsTo::class) ) { return null; } } catch (ReflectionException $exception) { return null; } return $guessedRelationshipName; } protected function guessBelongsToRelationshipTableName(string $column): ?string { $tableName = str($column)->beforeLast('_id'); if (Schema::hasTable(Str::plural($tableName))) { return Str::plural($tableName); } if (! Schema::hasTable($tableName)) { return null; } return $tableName; } protected function guessBelongsToRelationshipTitleColumnName(string $column, string $model): string { $schema = $this->getModelSchema($model); $table = $this->getModelTable($model); $columns = collect($schema->getColumnListing($table)); if ($columns->contains('name')) { return 'name'; } if ($columns->contains('title')) { return 'title'; } return collect($schema->getIndexes($table)) ->firstWhere('primary')['columns'][0] ?? 'id'; } /** * @param array $column * @return array */ protected function parseColumnType(array $column): array { $type = match ($column['type']) { 'tinyint(1)', 'bit' => 'boolean', 'varchar(max)', 'nvarchar(max)' => 'text', default => null, }; $type ??= match ($column['type_name']) { 'boolean', 'bool' => 'boolean', 'char', 'bpchar', 'nchar' => 'char', 'varchar', 'nvarchar' => 'string', 'integer', 'int', 'int4', 'tinyint', 'smallint', 'int2', 'mediumint', 'bigint', 'int8' => 'integer', 'decimal', 'numeric' => 'decimal', 'float', 'real', 'float4' => 'float', 'double', 'float8' => 'double', 'money', 'smallmoney' => 'money', 'date' => 'date', 'time', 'timetz' => 'time', 'datetime', 'datetime2', 'smalldatetime', 'datetimeoffset' => 'datetime', 'timestamp', 'timestamptz' => 'timestamp', 'text', 'tinytext', 'longtext', 'mediumtext', 'ntext' => 'text', 'json', 'jsonb' => 'json', default => $column['type_name'], }; $values = str_contains($column['type'], '(') ? str_getcsv(Str::between($column['type'], '(', ')'), enclosure: "'", escape: '\\') : null; $values = is_null($values) ? [] : match ($type) { 'string', 'char', 'binary', 'bit' => ['length' => (int) $values[0]], default => [], }; return array_merge(['name' => $type], array_filter($values)); } /** * @param array $column */ protected function parseDefaultExpression(array $column, string $model): mixed { $default = $column['default']; if (blank($default)) { return null; } $driver = app($model)->getConnection()->getDriverName(); if (in_array($driver, ['mysql', 'mariadb'])) { if ($default === 'NULL' || preg_match("/^\(.*\)$/", $default) === 1 || str_ends_with($default, '()') || str_starts_with(strtolower($default), 'current_timestamp')) { return null; } if (preg_match("/^'(.*)'$/", $default, $matches) === 1) { return str_replace("''", "'", $matches[1]); } } if ($driver === 'pgsql') { if (str_starts_with($default, 'NULL::')) { $default = null; } if (preg_match("/^['(](.*)[')]::/", $default, $matches) === 1) { return str_replace("''", "'", $matches[1]); } } if ($driver === 'sqlsrv') { while (preg_match('/^\((.*)\)$/', $default, $matches)) { $default = $matches[1]; } if ($default === 'NULL' || str_ends_with($default, '()')) { return null; } if (preg_match('/^\'(.*)\'$/', $default, $matches) === 1) { return str_replace("''", "'", $matches[1]); } } if ($driver === 'sqlite') { if ($default === 'NULL' || str_starts_with(strtolower($default), 'current_timestamp')) { return null; } if (preg_match('/^\'(.*)\'$/s', $default, $matches) === 1) { return str_replace("''", "'", $matches[1]); } } return $default; } }