Open alexsalzer opened 7 years ago
Labels: question, feature
This is not yet supported, we are open for pull requests.
Greetings, this feature, as I see it, has not yet been implemented. Is it planned for the next releases?
If you have interested multiple connection implement, I solved this problem by adding a connection parameter to SchemeManager. Though the connections parameters is hard coded but it might help some guys.
https://github.com/shota/voyager/blob/1.4/src/Database/Schema/SchemaManager.php
<?php
namespace TCG\Voyager\Database\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Schema\Table as DoctrineTable;
use Illuminate\Support\Facades\DB;
use TCG\Voyager\Database\Types\Type;
abstract class SchemaManager
{
// todo: trim parameters
static $connections = ['mysql','mysql_backend'];
public static function __callStatic($method, $args)
{
return static::manager()->$method(...$args);
}
public static function manager($connection = null)
{
return DB::connection($connection)->getDoctrineSchemaManager();
}
public static function getDatabaseConnection($connection = null)
{
return DB::connection($connection)->getDoctrineConnection();
}
public static function tableExists($table)
{
if (!is_array($table)) {
$table = [$table];
}
$matches = false;
foreach(static::$connections as $connection) {
$matches = $matches || static::manager($connection)->tablesExist($table);
}
// return static::tablesExist($table);
return $matches;
}
public static function listTables()
{
$tables = [];
foreach (static::listTableNames() as $tableName) {
$tables[$tableName] = static::listTableDetails($tableName);
}
return $tables;
}
public static function listTableNames() {
$tableNames = [];
foreach(static::$connections as $connection) {
$tableNames = array_merge(
$tableNames,
static::manager($connection)->listTableNames()
);
}
return $tableNames;
}
/**
* @param string $tableName
*
* @return \TCG\Voyager\Database\Schema\Table
*/
public static function listTableDetails($tableName)
{
$tableConnection = null;
foreach(static::$connections as $connection) {
if (static::manager($connection)->tablesExist([$tableName])) {
$tableConnection = $connection;
}
}
if (!$connection) {
throw new \Exception("No acceptable connection for table $tableName");
}
$columns = static::manager($connection)->listTableColumns($tableName);
$foreignKeys = [];
if (static::manager($connection)->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$foreignKeys = static::manager($connection)->listTableForeignKeys($tableName);
}
$indexes = static::manager($connection)->listTableIndexes($tableName);
return new Table($tableName, $columns, $indexes, $foreignKeys, false, []);
}
/**
* Describes given table.
*
* @param string $tableName
*
* @return \Illuminate\Support\Collection
*/
public static function describeTable($tableName)
{
Type::registerCustomPlatformTypes();
$table = static::listTableDetails($tableName);
return collect($table->columns)->map(function ($column) use ($table) {
$columnArr = Column::toArray($column);
$columnArr['field'] = $columnArr['name'];
$columnArr['type'] = $columnArr['type']['name'];
// Set the indexes and key
$columnArr['indexes'] = [];
$columnArr['key'] = null;
if ($columnArr['indexes'] = $table->getColumnsIndexes($columnArr['name'], true)) {
// Convert indexes to Array
foreach ($columnArr['indexes'] as $name => $index) {
$columnArr['indexes'][$name] = Index::toArray($index);
}
// If there are multiple indexes for the column
// the Key will be one with highest priority
$indexType = array_values($columnArr['indexes'])[0]['type'];
$columnArr['key'] = substr($indexType, 0, 3);
}
return $columnArr;
});
}
public static function listTableColumnNames($tableName)
{
Type::registerCustomPlatformTypes();
$columnNames = [];
foreach (static::manager()->listTableColumns($tableName) as $column) {
$columnNames[] = $column->getName();
}
return $columnNames;
}
public static function createTable($table)
{
if (!($table instanceof DoctrineTable)) {
$table = Table::make($table);
}
static::manager()->createTable($table);
}
public static function getDoctrineTable($table)
{
$table = trim($table);
if (!static::tableExists($table)) {
throw SchemaException::tableDoesNotExist($table);
}
return static::manager()->listTableDetails($table);
}
public static function getDoctrineColumn($table, $column)
{
return static::getDoctrineTable($table)->getColumn($column);
}
}
@shota can you please guide where we should place it and where it should be included?
@shota function listTableDetails($tableName)
always take the last connection
I fixed it
public static function listTableDetails($tableName) {
$tableConnection = null;
foreach(static::$connections as $connection) {
if (static::manager($connection)->tablesExist([$tableName])) {
$tableConnection = $connection;
}
}
if (!$tableConnection) {
throw new \Exception("No acceptable connection for table $tableName");
}
$columns = static::manager($tableConnection)->listTableColumns($tableName);
$foreignKeys = [];
if (static::manager($tableConnection)->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$foreignKeys = static::manager($tableConnection)->listTableForeignKeys($tableName);
}
$indexes = static::manager($tableConnection)->listTableIndexes($tableName);
return new Table($tableName, $columns, $indexes, $foreignKeys, false, []);
}
If after creating a new BREAD for the table you don't have any data, change the listTableColumnNames(TCG\Voyager\Database\Schema) method like this:
` public static function listTableColumnNames($tableName) { Type::registerCustomPlatformTypes();
$columnNames = [];
$tableConnection = null;
foreach(static::$connections as $connection) {
if (static::manager($connection)->tablesExist([$tableName])) {
$tableConnection = $connection;
}
}
foreach (static::manager($tableConnection)->listTableColumns($tableName) as $column) {
$columnNames[] = $column->getName();
}
return $columnNames;
}`
how to override this class. i do not want change class into vendor folder laravel
how to override this class. i do not want change class into vendor folder laravel
For override withou change class into vendor folder you can use AppServiceProvider:register function. Edit app\Providers\AppServiceProvider.php. The first argument of the alias() method must be a vendor class, and after is the overriding class (ref link):
<?php
namespace App\Providers;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Support\ServiceProvider;
use TCG\Voyager\Database\Schema\SchemaManager;
use TCG\Voyager\Database\Schema\Index;
use TCG\Voyager\Database\Schema\Table;
use TCG\Voyager\Database\Schema\Column;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$loader = AliasLoader::getInstance();
$loader->alias(SchemaManager::class, \App\Voyager\SchemaManager::class);
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
}
}
And into app\Voyager\SchemaManager.php create and paste this
<?php
namespace App\Voyager;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Schema\Table as DoctrineTable;
use Illuminate\Support\Facades\DB;
use TCG\Voyager\Database\Types\Type;
abstract class SchemaManager
{
// todo: trim parameters
static $connections = ['mysql', 'mysql_backend'];
public static function __callStatic($method, $args)
{
return static::manager()->$method(...$args);
}
public static function manager($connection = null)
{
return DB::connection($connection)->getDoctrineSchemaManager();
}
public static function getDatabaseConnection($connection = null)
{
return DB::connection($connection)->getDoctrineConnection();
}
public static function tableExists($table)
{
if (!is_array($table)) {
$table = [$table];
}
$matches = false;
foreach (static::$connections as $connection) {
$matches = $matches || static::manager($connection)->tablesExist($table);
}
// return static::tablesExist($table);
return $matches;
}
public static function listTables()
{
$tables = [];
foreach (static::listTableNames() as $tableName) {
$tables[$tableName] = static::listTableDetails($tableName);
}
return $tables;
}
public static function listTableNames()
{
$tableNames = [];
foreach (static::$connections as $connection) {
$tableNames = array_merge(
$tableNames,
static::manager($connection)->listTableNames()
);
}
return $tableNames;
}
/**
* @param string $tableName
*
* @return \TCG\Voyager\Database\Schema\Table
*/
public static function listTableDetails($tableName)
{
$tableConnection = null;
foreach (static::$connections as $connection) {
if (static::manager($connection)->tablesExist([$tableName])) {
$tableConnection = $connection;
}
}
if (!$tableConnection) {
throw new \Exception("No acceptable connection for table $tableName");
}
$columns = static::manager($tableConnection)->listTableColumns($tableName);
$foreignKeys = [];
if (static::manager($tableConnection)->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$foreignKeys = static::manager($tableConnection)->listTableForeignKeys($tableName);
}
$indexes = static::manager($tableConnection)->listTableIndexes($tableName);
return new Table($tableName, $columns, $indexes, $foreignKeys, false, []);
}
/**
* Describes given table.
*
* @param string $tableName
*
* @return \Illuminate\Support\Collection
*/
public static function describeTable($tableName)
{
Type::registerCustomPlatformTypes();
$table = static::listTableDetails($tableName);
return collect($table->columns)->map(function ($column) use ($table) {
$columnArr = Column::toArray($column);
$columnArr['field'] = $columnArr['name'];
$columnArr['type'] = $columnArr['type']['name'];
// Set the indexes and key
$columnArr['indexes'] = [];
$columnArr['key'] = null;
if ($columnArr['indexes'] = $table->getColumnsIndexes($columnArr['name'], true)) {
// Convert indexes to Array
foreach ($columnArr['indexes'] as $name => $index) {
$columnArr['indexes'][$name] = Index::toArray($index);
}
// If there are multiple indexes for the column
// the Key will be one with highest priority
$indexType = array_values($columnArr['indexes'])[0]['type'];
$columnArr['key'] = substr($indexType, 0, 3);
}
return $columnArr;
});
}
public static function listTableColumnNames($tableName)
{
Type::registerCustomPlatformTypes();
$tableConnection = null;
foreach (static::$connections as $connection) {
if (static::manager($connection)->tablesExist([$tableName])) {
$tableConnection = $connection;
}
}
foreach (static::manager($tableConnection)->listTableColumns($tableName) as $column) {
$columnNames[] = $column->getName();
}
return $columnNames;
}
public static function createTable($table)
{
if (!($table instanceof DoctrineTable)) {
$table = Table::make($table);
}
static::manager()->createTable($table);
}
public static function getDoctrineTable($table)
{
$table = trim($table);
if (!static::tableExists($table)) {
throw SchemaException::tableDoesNotExist($table);
}
return static::manager()->listTableDetails($table);
}
public static function getDoctrineColumn($table, $column)
{
return static::getDoctrineTable($table)->getColumn($column);
}
}
Don't forget duplicate the config of mysql into config\database.php with the key ´mysql_backend´ or your database name connection.
Thanks @shota, @vu-cv, @Kushelbek
Description:
I do have multiple databases which works quite well within a Laravel App.
How can I configure Voyager to use them?
Is it possible to switch between connections?
Kind Regards
Steps To Reproduce: