Voyager: Multiple Database

Created on 13 Sep 2017  路  4Comments  路  Source: the-control-group/voyager

  • Laravel Version: 5.4.*
  • Voyager Version: ^0.11.14
  • PHP Version: 7.1.8
  • Database Driver & Version: MariaDB 5.5.52

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:

  • new laravel project and installation of voyager with all required steps
  • create a new databases
  • setup new database connections in database.php config
  • just default one is present
feature help wanted

Most helpful comment

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);
    }
}

All 4 comments

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);
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

IvanBohonosiuk picture IvanBohonosiuk  路  4Comments

TPRAsh picture TPRAsh  路  3Comments

duongsieu picture duongsieu  路  3Comments

ferrywae picture ferrywae  路  4Comments

craigb88 picture craigb88  路  3Comments