Add database support.

This commit is contained in:
flash 2018-01-03 20:50:29 +01:00
parent 6fd82da2d9
commit 61700fa782
5 changed files with 210 additions and 5 deletions

View file

@ -1 +1,42 @@
; Example configuration for Misuzu
[Database]
default = mysql_example
connections = mysql_example sqlite_example postgres_example sqlsrv_example
[Database.mysql_example]
driver = mysql
host = localhost
port = 3306
username = username
password = password
prefix = prefix_
database = database
charset = utf8mb4
collation = utf8mb4_bin
[Database.sqlite_example]
driver = sqlite_example
database = store/database.db3
prefix =
[Database.postgres_example]
driver = pgsql
host = localhost
port = 5432
username = username
password = password
prefix = prefix_
database = database
charset = utf8
schema = public
[Database.sqlsrv_example]
driver = sqlsrv
host = localhost
port = 1433
username = username
password = password
prefix = prefix_
database = database
charset = utf8

View file

@ -3,6 +3,6 @@ namespace Misuzu;
require_once 'vendor/autoload.php'; require_once 'vendor/autoload.php';
$app = Application::start(); $app = Application::start(__DIR__ . '/config/config.ini');
$app->debug(IO\Directory::exists(__DIR__ . '/vendor/phpunit/phpunit')); $app->debug(IO\Directory::exists(__DIR__ . '/vendor/phpunit/phpunit'));
$app->router->add(include_once __DIR__ . '/routes.php'); $app->router->add(include_once __DIR__ . '/routes.php');

View file

@ -17,13 +17,13 @@ class Application
return static::$instance; return static::$instance;
} }
public static function start(): Application public static function start(...$params): Application
{ {
if (!is_null(static::$instance) || static::$instance instanceof Application) { if (!is_null(static::$instance) || static::$instance instanceof Application) {
throw new \Exception('An Application has already been set up.'); throw new \Exception('An Application has already been set up.');
} }
static::$instance = new Application; static::$instance = new Application(...$params);
return static::getInstance(); return static::getInstance();
} }
@ -61,10 +61,17 @@ class Application
protected function __construct($configFile = null) protected function __construct($configFile = null)
{ {
ExceptionHandler::register(); ExceptionHandler::register();
$this->debug(true);
$this->addModule('config', $config = new ConfigManager($configFile));
$this->addModule('database', new Database(
$config,
$config->get('Database', 'default', 'string', 'default')
));
$this->addModule('router', $router = new RouteCollection); $this->addModule('router', $router = new RouteCollection);
$this->addModule('templating', $twig = new TemplateEngine); $this->addModule('templating', $twig = new TemplateEngine);
$this->addModule('config', $config = new ConfigManager($configFile));
$this->loadConfigDatabaseConnections();
$twig->addFilter('json_decode'); $twig->addFilter('json_decode');
$twig->addFilter('byte_symbol'); $twig->addFilter('byte_symbol');
@ -79,9 +86,35 @@ class Application
public function __destruct() public function __destruct()
{ {
if ($this->hasConfig) {
$this->config->save();
}
ExceptionHandler::unregister(); ExceptionHandler::unregister();
} }
private function loadConfigDatabaseConnections(): void
{
$config = $this->config;
$database = $this->database;
if ($config->contains('Database', 'connections')) {
$connections = explode(' ', $config->get('Database', 'connections'));
foreach ($connections as $name) {
$section = 'Database.' . $name;
if (!$config->contains($section)) {
continue;
}
$database->addConnectionFromConfig($section, $name);
}
} else {
throw new \Exception('No database connections have been configured.');
}
}
public function debug(bool $mode): void public function debug(bool $mode): void
{ {
ExceptionHandler::debug($mode); ExceptionHandler::debug($mode);

View file

@ -2,12 +2,14 @@
namespace Misuzu\Controllers; namespace Misuzu\Controllers;
use Misuzu\Application; use Misuzu\Application;
use Misuzu\Database;
class HomeController extends Controller class HomeController extends Controller
{ {
public function index(): string public function index(): string
{ {
$twig = Application::getInstance()->templating; $app = Application::getInstance();
$twig = $app->templating;
return $twig->render('home.landing'); return $twig->render('home.landing');
} }

129
src/Database.php Normal file
View file

@ -0,0 +1,129 @@
<?php
namespace Misuzu;
use Illuminate\Database\Capsule\Manager as LaravelDatabaseManager;
use Misuzu\Config\ConfigManager;
class Database extends LaravelDatabaseManager
{
private $configManager;
private const SUPPORTED_DB_ALS = [
'mysql',
'sqlite',
'pgsql',
'sqlsrv',
];
public function __construct(
ConfigManager $config,
string $default = 'default',
bool $startEloquent = true,
bool $setAsGlobal = true
) {
$this->configManager = $config;
parent::__construct();
$this->container['config']['database.default'] = $default;
if ($startEloquent) {
$this->bootEloquent();
}
if ($setAsGlobal) {
$this->setAsGlobal();
}
}
public function addConnectionFromConfig(string $section, string $name = 'default'): void
{
if (!$this->configManager->contains($section, 'driver')) {
throw new \Exception('Config section not found!');
}
$driver = $this->configManager->get($section, 'driver');
if (!in_array($driver, self::SUPPORTED_DB_ALS)) {
throw new \Exception('Unsupported driver.');
}
$args = [
'driver' => $driver,
'database' => $this->configManager->get($section, 'database', 'string', 'misuzu'),
'prefix' => $this->configManager->get($section, 'prefix', 'string', ''),
];
switch ($driver) {
case 'mysql':
$is_unix_socket = $this->configManager->contains($section, 'unix_socket');
$args['host'] = $is_unix_socket
? ''
: $this->configManager->get($section, 'host', 'string', '127.0.0.1');
$args['port'] = $is_unix_socket
? 3306
: $this->configManager->get($section, 'port', 'int', 3306);
$args['username'] = $this->configManager->get($section, 'username', 'string');
$args['password'] = $this->configManager->get($section, 'password', 'string');
$args['unix_socket'] = $is_unix_socket
? $this->configManager->get($section, 'unix_socket', 'string')
: '';
// these should probably be locked to these types
$args['charset'] = $this->configManager->contains($section, 'charset')
? $this->configManager->get($section, 'charset', 'string')
: 'utf8mb4';
$args['collation'] = $this->configManager->contains($section, 'collation')
? $this->configManager->get($section, 'collation', 'string')
: 'utf8mb4_bin';
$args['strict'] = true;
$args['engine'] = null;
break;
case 'pgsql':
$is_unix_socket = $this->configManager->contains($section, 'unix_socket');
$args['host'] = $is_unix_socket
? ''
: $this->configManager->get($section, 'host', 'string', '127.0.0.1');
$args['port'] = $is_unix_socket
? 5432
: $this->configManager->get($section, 'port', 'int', 5432);
$args['username'] = $this->configManager->get($section, 'username', 'string');
$args['password'] = $this->configManager->get($section, 'password', 'string');
$args['unix_socket'] = $is_unix_socket
? $this->configManager->get($section, 'unix_socket', 'string')
: '';
// these should probably be locked to these types
$args['charset'] = $this->configManager->contains($section, 'charset')
? $this->configManager->get($section, 'charset', 'string')
: 'utf8';
$args['schema'] = 'public';
$args['sslmode'] = 'prefer';
break;
case 'sqlsrv':
$args['host'] = $this->configManager->get($section, 'host', 'string', '127.0.0.1');
$args['port'] = $this->configManager->get($section, 'port', 'int', 1433);
$args['username'] = $this->configManager->get($section, 'username', 'string');
$args['password'] = $this->configManager->get($section, 'password', 'string');
// these should probably be locked to these types
$args['charset'] = $this->configManager->contains($section, 'charset')
? $this->configManager->get($section, 'charset', 'string')
: 'utf8';
break;
}
$this->addConnection($args, $name);
}
}