Files
2026-03-07 19:42:22 +08:00

184 lines
6.4 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace ba;
use Throwable;
use support\think\Db;
use Phinx\Db\Table;
use Phinx\Db\Adapter\AdapterFactory;
use Phinx\Db\Adapter\AdapterInterface;
/**
* 数据表管理类
* 使用 thinkorm 配置Phinx 适配器
*/
class TableManager
{
/**
* 返回一个 Phinx/Db/Table 实例 用于操作数据表
* @param string $table 表名
* @param array $options 传递给 Phinx/Db/Table 的 options
* @param bool $prefixWrapper 是否使用表前缀包装表名
* @param ?string $connection 连接配置标识
* @return Table
* @throws Throwable
*/
public static function phinxTable(string $table, array $options = [], bool $prefixWrapper = true, ?string $connection = null): Table
{
return new Table($table, $options, self::phinxAdapter($prefixWrapper, $connection));
}
/**
* 返回 Phinx\Db\Adapter\AdapterFactory (适配器/连接驱动)实例
* @param bool $prefixWrapper 是否使用表前缀包装表名
* @param ?string $connection 连接配置标识
* @return AdapterInterface
* @throws Throwable
*/
public static function phinxAdapter(bool $prefixWrapper = true, ?string $connection = null): AdapterInterface
{
$config = static::getPhinxDbConfig($connection);
$factory = AdapterFactory::instance();
$adapter = $factory->getAdapter($config['adapter'], $config);
if ($prefixWrapper) return $factory->getWrapper('prefix', $adapter);
return $adapter;
}
/**
* 数据表名
* @param string $table 表名,带不带前缀均可
* @param bool $fullName 是否返回带前缀的表名
* @param ?string $connection 连接配置标识
* @return string 表名
* @throws Exception
*/
public static function tableName(string $table, bool $fullName = true, ?string $connection = null): string
{
$connectionConfig = self::getConnectionConfig($connection);
$pattern = '/^' . preg_quote($connectionConfig['prefix'], '/') . '/i';
return ($fullName ? $connectionConfig['prefix'] : '') . preg_replace($pattern, '', $table);
}
/**
* 数据表列表
* @param ?string $connection 连接配置标识
* @throws Exception
*/
public static function getTableList(?string $connection = null): array
{
$tableList = [];
$config = self::getConnectionConfig($connection);
$connName = self::getConnection($connection);
$tables = Db::connect($connName)->query("SELECT TABLE_NAME,TABLE_COMMENT FROM information_schema.TABLES WHERE table_schema = ? ", [$config['database']]);
foreach ($tables as $row) {
$tableList[$row['TABLE_NAME']] = $row['TABLE_NAME'] . ($row['TABLE_COMMENT'] ? ' - ' . $row['TABLE_COMMENT'] : '');
}
return $tableList;
}
/**
* 获取数据表所有列
* @param string $table 数据表名
* @param bool $onlyCleanComment 只要干净的字段注释信息
* @param ?string $connection 连接配置标识
* @throws Throwable
*/
public static function getTableColumns(string $table, bool $onlyCleanComment = false, ?string $connection = null): array
{
if (!$table) return [];
$table = self::tableName($table, true, $connection);
$config = self::getConnectionConfig($connection);
$connName = self::getConnection($connection);
$sql = "SELECT * FROM `information_schema`.`columns` "
. "WHERE TABLE_SCHEMA = ? AND table_name = ? "
. "ORDER BY ORDINAL_POSITION";
$columnList = Db::connect($connName)->query($sql, [$config['database'], $table]);
$fieldList = [];
foreach ($columnList as $item) {
if ($onlyCleanComment) {
$fieldList[$item['COLUMN_NAME']] = '';
if ($item['COLUMN_COMMENT']) {
$comment = explode(':', $item['COLUMN_COMMENT']);
$fieldList[$item['COLUMN_NAME']] = $comment[0];
}
continue;
}
$fieldList[$item['COLUMN_NAME']] = $item;
}
return $fieldList;
}
/**
* 系统是否存在多个数据库连接配置
*/
public static function isMultiDatabase(): bool
{
return count(config('thinkorm.connections', [])) > 1;
}
/**
* 获取数据库连接配置标识
* @param ?string $source
* @return string 连接配置标识
*/
public static function getConnection(?string $source = null): string
{
if (!$source || $source === 'default') {
return config('thinkorm.default', 'mysql');
}
return $source;
}
/**
* 获取某个数据库连接的配置数组
* @param ?string $connection 连接配置标识
* @throws Exception
*/
public static function getConnectionConfig(?string $connection = null): array
{
$connName = self::getConnection($connection);
$connection = config("thinkorm.connections.{$connName}");
if (!is_array($connection)) {
throw new Exception('Database connection configuration error');
}
// 分布式
if (($connection['deploy'] ?? 0) == 1) {
$keys = ['type', 'hostname', 'database', 'username', 'password', 'hostport', 'charset', 'prefix'];
foreach ($connection as $key => $item) {
if (in_array($key, $keys)) {
$connection[$key] = is_array($item) ? $item[0] : explode(',', $item)[0];
}
}
}
return $connection;
}
/**
* 获取 Phinx 适配器需要的数据库配置
* @param ?string $connection 连接配置标识
* @return array
* @throws Throwable
*/
protected static function getPhinxDbConfig(?string $connection = null): array
{
$config = self::getConnectionConfig($connection);
$connName = self::getConnection($connection);
$db = Db::connect($connName);
$db->query('SELECT 1');
$table = config('thinkorm.migration_table', 'migrations');
return [
'adapter' => $config['type'],
'connection' => $db->getPdo(),
'name' => $config['database'],
'table_prefix' => $config['prefix'],
'migration_table' => $config['prefix'] . $table,
];
}
}