first commit

This commit is contained in:
Maxime Rault 2015-04-22 14:41:53 +02:00
commit 3e0acb478d
13 changed files with 1696 additions and 0 deletions

0
LICENSE.md Normal file
View File

130
README.md Normal file
View File

@ -0,0 +1,130 @@
# laravel-db2
[![Latest Stable Version](https://poser.pugx.org/cooperl/laravel-db2/v/stable)](https://packagist.org/packages/cooperl/laravel-db2)
[![Total Downloads](https://poser.pugx.org/cooperl/laravel-db2/downloads)](https://packagist.org/packages/cooperl/laravel-db2)
[![Latest Unstable Version](https://poser.pugx.org/cooperl/laravel-db2/v/unstable)](https://packagist.org/packages/cooperl/laravel-db2)
[![License](https://poser.pugx.org/cooperl/laravel-db2/license)](https://packagist.org/packages/cooperl/laravel-db2)
laravel-db2 is a simple DB2 service provider for Laravel.
It provides DB2 Connection by extending the Illuminate Database component of the laravel framework.
---
- [Installation](#installation)
- [Registering the Package](#registering-the-package)
- [Configuration](#configuration)
- [Usage](#usage)
## Installation
Add laravel-db2 to your composer.json file:
```
"require": {
"cooperl/laravel-db2": "~1.0"
}
```
Use [composer](http://getcomposer.org) to install this package.
```
$ composer update
```
### Registering the Package
Add the laravel-db2 Service Provider to your config in ``app/config/app.php``:
```php
'providers' => [
'Cooperl\Database\DB2\DB2ServiceProvider'
],
```
### Configuration
There are two ways to configure laravel-db2. You can choose the most convenient way for you. You can put your DB2 credentials into ``app/config/database.php`` (option 1) file or use package config file which you can be generated through command line by artisan (option 2).
#### Option 1: Configure DB2 using ``app/config/database.php`` file
Simply add this code at the end of your ``app/config/database.php`` file:
```php
/*
|--------------------------------------------------------------------------
| DB2 Databases
|--------------------------------------------------------------------------
*/
'odbc' => [
'driver' => 'odbc',
'host' => '',
'database' => '',
'username' => '',
'password' => '',
'charset' => 'utf8',
'ccsid' => 1208,
'prefix' => '',
'schema' => '',
'i5_libl' => '',
'i5_lib' => '',
'i5_commit' => 0,
'i5_naming' => 0,
'i5_date_fmt' => 5,
'i5_date_sep' => 0,
'i5_decimal_sep' => 0,
'i5_time_fmt' => 0,
'i5_time_sep' => 0,
'options' => [
PDO::ATTR_CASE => PDO::CASE_LOWER,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_PERSISTENT => false
]
],
'ibm' => [
'driver' => 'ibm',
'host' => '',
'database' => '',
'username' => '',
'password' => '',
'charset' => 'utf8',
'ccsid' => 1208,
'prefix' => '',
'schema' => '',
'i5_libl' => '',
'i5_lib' => '',
'i5_commit' => 0,
'i5_naming' => 0,
'i5_date_fmt' => 5,
'i5_date_sep' => 0,
'i5_decimal_sep' => 0,
'i5_time_fmt' => 0,
'i5_time_sep' => 0,
'options' => [
PDO::ATTR_CASE => PDO::CASE_LOWER,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_PERSISTENT => false
]
],
```
driver setting is either 'odbc' for ODBC connection or 'ibm' for pdo_ibm connection
Then if driver is 'odbc', database must be set to ODBC connection name.
if driver is 'ibm', database must be set to IBMi database name (WRKRDBDIRE).
#### Option 2: Configure DB2 using package config file
Run on the command line from the root of your project:
```
$ php artisan config:publish cooperl/laravel-db2
```
Set your laravel-db2 credentials in ``app/config/packages/cooperl/laravel-db2/config.php``
the same way as above
## Usage
Consult the [Laravel framework documentation](http://laravel.com/docs).

29
composer.json Normal file
View File

@ -0,0 +1,29 @@
{
"name": "cooperl/laravel-db2",
"description": "laravel-db2 is a simple DB2 service provider for Laravel. It provides DB2 Connection by extending the Illuminate Database component of the laravel framework.",
"keywords": ["laravel", "DB2", "Database", "PDO", "ODBC"],
"license": "MIT",
"authors": [
{
"name": "Maxime Rault",
"role": "Developer"
}
],
"require": {
"php": ">=5.4.0",
"illuminate/support": "~4.2",
"illuminate/database": "~4.2"
},
"require-dev": {
},
"autoload": {
"psr-4": {
"Cooperl\\Database\\DB2\\": "src/"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace Cooperl\Database\DB2\Connectors;
use Illuminate\Database\Connectors\Connector;
use Illuminate\Database\Connectors\ConnectorInterface;
class IBMConnector extends Connector implements ConnectorInterface
{
public function connect(array $config)
{
$dsn = $this->getDsn($config);
$options = $this->getOptions($config);
$connection = $this->createConnection($dsn, $config, $options);
if (isset($config['schema']))
{
$schema = $config['schema'];
$connection->prepare("set schema $schema")->execute();
}
return $connection;
}
protected function getDsn(array $config) {
extract($config);
$dsn = "ibm:$database";
return $dsn;
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace Cooperl\Database\DB2\Connectors;
use Illuminate\Database\Connectors\Connector;
use Illuminate\Database\Connectors\ConnectorInterface;
class ODBCConnector extends Connector implements ConnectorInterface
{
public function connect(array $config)
{
$dsn = $this->getDsn($config);
$options = $this->getOptions($config);
$connection = $this->createConnection($dsn, $config, $options);
if (isset($config['schema']))
{
$schema = $config['schema'];
$connection->prepare("set schema $schema")->execute();
}
return $connection;
}
protected function getDsn(array $config) {
extract($config);
$dsn = "odbc:DRIVER={iSeries Access ODBC Driver};"
. "SYSTEM=$database;"
. "NAM=$i5_naming;"
. "DATABASE=$i5_lib;"
. "DBQ=$i5_libl;"
. "DFT=$i5_date_fmt;"
. "DSP=$i5_date_sep;"
. "DEC=$i5_decimal_sep;"
. "TFT=$i5_time_fmt;"
. "TSP=$i5_time_sep;"
. "CCSID=$ccsid";
return $dsn;
}
}

100
src/DB2Connection.php Normal file
View File

@ -0,0 +1,100 @@
<?php
namespace Cooperl\Database\DB2;
use PDO;
use Illuminate\Database\Connection;
use Cooperl\Database\DB2\Schema\Builder;
use Cooperl\Database\DB2\Query\Processors\DB2Processor;
use Cooperl\Database\DB2\Query\Grammars\DB2Grammar as QueryGrammar;
use Cooperl\Database\DB2\Schema\Grammars\DB2Grammar as SchemaGrammar;
class DB2Connection extends Connection
{
/**
* The name of the default schema.
*
* @var string
*/
protected $defaultSchema;
public function __construct(PDO $pdo, $database = '', $tablePrefix = '', array $config = [])
{
parent::__construct($pdo, $database, $tablePrefix, $config);
$this->currentSchema = $this->defaultSchema = strtoupper($config['schema']);
}
/**
* Get the name of the default schema.
*
* @return string
*/
public function getDefaultSchema()
{
return $this->defaultSchema;
}
/**
* Reset to default the current schema.
*
* @return string
*/
public function resetCurrentSchema()
{
$this->setCurrentSchema($this->getDefaultSchema());
}
/**
* Set the name of the current schema.
*
* @return string
*/
public function setCurrentSchema($schema)
{
//$this->currentSchema = $schema;
$this->statement('SET SCHEMA ?', [strtoupper($schema)]);
}
/**
* Get a schema builder instance for the connection.
*
* @return \Illuminate\Database\Schema\MySqlBuilder
*/
public function getSchemaBuilder()
{
if (is_null($this->schemaGrammar)) { $this->useDefaultSchemaGrammar(); }
return new Builder($this);
}
/**
* @return Query\Grammars\Grammar
*/
protected function getDefaultQueryGrammar()
{
return $this->withTablePrefix(new QueryGrammar);
}
/**
* Default grammar for specified Schema
* @return Schema\Grammars\Grammar
*/
protected function getDefaultSchemaGrammar()
{
return $this->withTablePrefix(new SchemaGrammar);
}
/**
* Get the default post processor instance.
*
* @return \Illuminate\Database\Query\Processors\PostgresProcessor
*/
protected function getDefaultPostProcessor()
{
return new DB2Processor;
}
}

View File

@ -0,0 +1,84 @@
<?php
namespace Cooperl\Database\DB2;
use Cooperl\Database\DB2\Connectors\ODBCConnector;
use Cooperl\Database\DB2\Connectors\IBMConnector;
use Illuminate\Support\ServiceProvider;
use Illuminate\Foundation\AliasLoader;
use Config;
class DB2ServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
// get the configs
$conns = is_array(Config::get('laravel-db2::database.connections')) ? Config::get('laravel-db2::database.connections') : [];
// Add my database configurations to the default set of configurations
$this->app['config']['database.connections'] = array_merge($conns, $this->app['config']['database.connections']);
//Extend the connections with pdo_odbc and pdo_ibm drivers
foreach(Config::get('database.connections') as $conn => $config)
{
//Only use configurations that feature a "odbc" or "ibm" driver
if(!isset($config['driver']) || !in_array($config['driver'], ['odbc', 'ibm']) )
{
continue;
}
//Create a connector
$this->app['db']->extend($conn, function($config)
{
switch ($config['driver']) {
case 'odbc':
$connector = new ODBCConnector();
break;
case 'ibm':
$connector = new IBMConnector();
break;
default:
break;
}
$db2Connection = $connector->connect($config);
return new DB2Connection($db2Connection, $config["database"], $config["prefix"], $config);
});
}
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [];
}
}

View File

@ -0,0 +1,150 @@
<?php
namespace Cooperl\Database\DB2\Query\Grammars;
use Illuminate\Database\Query\Grammars\Grammar;
use Illuminate\Database\Query\Builder;
class DB2Grammar extends Grammar
{
/**
* Wrap a single string in keyword identifiers.
*
* @param string $value
* @return string
*/
protected function wrapValue($value)
{
if ($value === '*') return $value;
return str_replace('"', '""', $value);
}
/**
* Compile the "limit" portions of the query.
*
* @param Illuminate\Database\Query\Builder $query
* @param int $limit
* @return string
*/
protected function compileLimit(Builder $query, $limit)
{
return "FETCH FIRST $limit ROWS ONLY";
}
/**
* Compile a select query into SQL.
*
* @param Illuminate\Database\Query\Builder
* @return string
*/
public function compileSelect(Builder $query)
{
$components = $this->compileComponents($query);
// If an offset is present on the query, we will need to wrap the query in
// a big "ANSI" offset syntax block. This is very nasty compared to the
// other database systems but is necessary for implementing features.
if ($query->offset > 0)
{
return $this->compileAnsiOffset($query, $components);
}
return $this->concatenate($components);
}
/**
* Create a full ANSI offset clause for the query.
*
* @param Illuminate\Database\Query\Builder $query
* @param array $components
* @return string
*/
protected function compileAnsiOffset(Builder $query, $components)
{
// An ORDER BY clause is required to make this offset query work, so if one does
// not exist we'll just create a dummy clause to trick the database and so it
// does not complain about the queries for not having an "order by" clause.
if ( ! isset($components['orders']))
{
$components['orders'] = 'order by 1';
}
unset($components['limit']);
// We need to add the row number to the query so we can compare it to the offset
// and limit values given for the statements. So we will add an expression to
// the "select" that will give back the row numbers on each of the records.
$orderings = $components['orders'];
$columns = (!empty($components['columns']) ? $components['columns'] . ', ': 'select');
$components['columns'] = $this->compileOver($orderings, $columns);
unset($components['orders']);
// Next we need to calculate the constraints that should be placed on the query
// to get the right offset and limit from our query but if there is no limit
// set we will just handle the offset only since that is all that matters.
$start = $query->offset + 1;
$constraint = $this->compileRowConstraint($query);
$sql = $this->concatenate($components);
// We are now ready to build the final SQL query so we'll create a common table
// expression from the query and get the records with row numbers within our
// given limit and offset value that we just put on as a query constraint.
return $this->compileTableExpression($sql, $constraint);
}
/**
* Compile the over statement for a table expression.
*
* @param string $orderings
* @return string
*/
protected function compileOver($orderings, $columns)
{
return "{$columns} row_number() over ({$orderings}) as row_num";
}
protected function compileRowConstraint($query)
{
$start = $query->offset + 1;
if ($query->limit > 0)
{
$finish = $query->offset + $query->limit;
return "between {$start} and {$finish}";
}
return ">= {$start}";
}
/**
* Compile a common table expression for a query.
*
* @param string $sql
* @param string $constraint
* @return string
*/
protected function compileTableExpression($sql, $constraint)
{
return "select * from ({$sql}) as temp_table where row_num {$constraint}";
}
/**
* Compile the "offset" portions of the query.
*
* @param Illuminate\Database\Query\Builder $query
* @param int $offset
* @return string
*/
protected function compileOffset(Builder $query, $offset)
{
return '';
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace Cooperl\Database\DB2\Query\Processors;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Query\Processors\Processor;
use Cooperl\Database\DB2\Query\Grammars\DB2Grammar;
class DB2Processor extends Processor {
/**
* Process an "insert get ID" query.
*
* @param \Illuminate\Database\Query\Builder $query
* @param string $sql
* @param array $values
* @param string $sequence
* @return int/array
*/
public function processInsertGetId(Builder $query, $sql, $values, $sequence = null)
{
$sequenceStr = $sequence ?: 'id';
if (is_array($sequence))
{
$grammar = new DB2Grammar;
$sequenceStr = $grammar->columnize($sequence);
}
$sql = 'select ' . $sequenceStr . ' from new table (' . $sql;
$sql .= ')';
$results = $query->getConnection()->select($sql, $values);
if (is_array($sequence))
{
return array_values((array) $results[0]);
}
else
{
$result = (array) $results[0];
$id = $result[$sequenceStr];
return is_numeric($id) ? (int) $id : $id;
}
}
}

96
src/Schema/Blueprint.php Normal file
View File

@ -0,0 +1,96 @@
<?php
namespace Cooperl\Database\DB2\Schema;
class Blueprint extends \Illuminate\Database\Schema\Blueprint {
/**
* Specify a system name for the table.
*
* @param string $systemName
*/
public function forSystemName($systemName)
{
$this->systemName = $systemName;
}
/**
* Specify a label for the table.
*
* @param string $label
* @return \Illuminate\Support\Fluent
*/
public function label($label)
{
return $this->addCommand('label', compact('label'));
}
/**
* Add a new index command to the blueprint.
*
* @param string $type
* @param string|array $columns
* @param string $index
* @return \Illuminate\Support\Fluent
*/
protected function indexCommand($type, $columns, $index)
{
$columns = (array) $columns;
switch ($type) {
case 'index':
$indexSystem = false;
if (!is_null($index))
{
$indexSystem = $index;
}
$index = $this->createIndexName($type, $columns);
return $this->addCommand($type, compact('index', 'indexSystem', 'columns'));
break;
default:
break;
}
// If no name was specified for this index, we will create one using a basic
// convention of the table name, followed by the columns, followed by an
// index type, such as primary or index, which makes the index unique.
if (is_null($index))
{
$index = $this->createIndexName($type, $columns);
}
return $this->addCommand($type, compact('index', 'columns'));
}
/**
* Create a new boolean column on the table.
*
* @param string $column
* @return \Illuminate\Support\Fluent
*/
public function boolean($column)
{
$prefix = $this->table;
// Aucune utilité d'avoir le nom du schéma dans le préfixe de la contrainte check pour le type booléen
$schemaTable = explode(".", $this->table);
if (count($schemaTable) > 1)
{
$prefix = $schemaTable[1];
}
return $this->addColumn('boolean', $column, ['prefix' => $prefix]);
}
/**
* Create a new numeric column on the table.
*
* @param string $column
* @param int $total
* @param int $places
* @return \Illuminate\Support\Fluent
*/
public function numeric($column, $total = 8, $places = 2)
{
return $this->addColumn('numeric', $column, compact('total', 'places'));
}
}

89
src/Schema/Builder.php Normal file
View File

@ -0,0 +1,89 @@
<?php
namespace Cooperl\Database\DB2\Schema;
use Closure;
use Illuminate\Database\Schema\Blueprint;
class Builder extends \Illuminate\Database\Schema\Builder {
/**
* Determine if the given table exists.
*
* @param string $table
* @return bool
*/
public function hasTable($table)
{
$sql = $this->grammar->compileTableExists();
$schemaTable = explode(".", $table);
if (count($schemaTable) > 1)
{
$schema = $schemaTable[0];
$table = $this->connection->getTablePrefix().$schemaTable[1];
}
else
{
$schema = $this->connection->getDefaultSchema();
$table = $this->connection->getTablePrefix().$table;
}
return count($this->connection->select($sql, [$schema, $table])) > 0;
}
/**
* Get the column listing for a given table.
*
* @param string $table
* @return array
*/
public function getColumnListing($table)
{
$sql = $this->grammar->compileColumnExists();
$database = $this->connection->getDatabaseName();
$table = $this->connection->getTablePrefix().$table;
$results = $this->connection->select($sql, [$database, $table]);
return $this->connection->getPostProcessor()->processColumnListing($results);
}
/**
* Execute the blueprint to build / modify the table.
*
* @param \Cooperl\Database\DB2\Schema\Blueprint $blueprint
* @return void
*/
protected function build(Blueprint $blueprint)
{
$schemaTable = explode(".", $blueprint->getTable());
if (count($schemaTable) > 1)
{
$this->connection->setCurrentSchema($schemaTable[0]);
}
$blueprint->build($this->connection, $this->grammar);
$this->connection->resetCurrentSchema();
}
/**
* Create a new command set with a Closure.
*
* @param string $table
* @param \Closure $callback
* @return \Cooperl\Database\DB2\Schema\Blueprint
*/
protected function createBlueprint($table, Closure $callback = null)
{
if (isset($this->resolver))
{
return call_user_func($this->resolver, $table, $callback);
}
return new \Cooperl\Database\DB2\Schema\Blueprint($table, $callback);
}
}

View File

@ -0,0 +1,777 @@
<?php
namespace Cooperl\Database\DB2\Schema\Grammars;
use Illuminate\Support\Fluent;
use Illuminate\Database\Connection;
use Illuminate\Database\Schema\Grammars\Grammar;
use Illuminate\Database\Schema\Blueprint;
class DB2Grammar extends Grammar {
/**
* The possible column modifiers.
*
* @var array
*/
protected $preModifiers = ['ForColumn'];
protected $modifiers = ['Nullable', 'Default', 'Generated', 'Increment', 'StartWith', 'Before', 'ImplicitlyHidden'];
/**
* The possible column serials
*
* @var array
*/
protected $serials = ['bigInteger', 'integer', 'smallInteger'];
/**
* Wrap a single string in keyword identifiers.
*
* @param string $value
* @return string
*/
protected function wrapValue($value)
{
if ($value === '*') return $value;
return str_replace('"', '""', $value);
}
/**
* Compile the query to determine the list of tables.
*
* @return string
*/
public function compileTableExists()
{
return 'select * from information_schema.tables where table_schema = upper(?) and table_name = upper(?)';
}
/**
* Compile the query to determine the list of columns.
*
* @param string $table
* @return string
*/
public function compileColumnExists()
{
return "select column_name from information_schema.columns where table_schema = upper(?) and table_name = upper(?)";
}
/**
* Compile a create table command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @param \Illuminate\Database\Connection $connection
* @return string
*/
public function compileCreate(Blueprint $blueprint, Fluent $command, Connection $connection)
{
$columns = implode(', ', $this->getColumns($blueprint));
$sql = 'create table '.$this->wrapTable($blueprint);
if (isset($blueprint->systemName))
{
$sql .= ' for system name '.$blueprint->systemName;
}
$sql .= " ($columns)";
return $sql;
}
/**
* Compile a label command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @param \Illuminate\Database\Connection $connection
* @return string
*/
public function compileLabel(Blueprint $blueprint, Fluent $command, Connection $connection)
{
return 'label on table '.$this->wrapTable($blueprint).' is \'' . $command->label . '\'';
}
/**
* Compile the blueprint's column definitions.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @return array
*/
protected function getColumns(Blueprint $blueprint)
{
$columns = [];
foreach ($blueprint->getColumns() as $column)
{
// Each of the column types have their own compiler functions which are tasked
// with turning the column definition into its SQL format for this platform
// used by the connection. The column's modifiers are compiled and added.
//$sql = $this->wrap($column).' '.$this->getType($column);
$sql = $this->addPreModifiers($this->wrap($column), $blueprint, $column);
$sql .= ' '.$this->getType($column);
$columns[] = $this->addModifiers($sql, $blueprint, $column);
}
return $columns;
}
/**
* Add the column modifiers to the definition.
*
* @param string $sql
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function addPreModifiers($sql, Blueprint $blueprint, Fluent $column)
{
foreach ($this->preModifiers as $preModifier)
{
if (method_exists($this, $method = "modify{$preModifier}"))
{
$sql .= $this->{$method}($blueprint, $column);
}
}
return $sql;
}
/**
* Compile a create table command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileAdd(Blueprint $blueprint, Fluent $command)
{
$table = $this->wrapTable($blueprint);
$columns = $this->prefixArray('add', $this->getColumns($blueprint));
foreach ($columns as $column)
{
$statements[] = 'alter table '.$table.' '.$column;
}
return $statements;
}
/**
* Compile a primary key command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compilePrimary(Blueprint $blueprint, Fluent $command)
{
$table = $this->wrapTable($blueprint);
$columns = $this->columnize($command->columns);
// Aucune utilité d'avoir le nom du schéma dans le nom de la contrainte Primary
$schemaTable = explode(".", $table);
if (count($schemaTable) > 1)
{
$command->index = str_replace($schemaTable[0]."_", "", $command->index);
}
return "alter table {$table} add constraint {$command->index} primary key ({$columns})";
}
/**
* Compile a foreign key command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileForeign(Blueprint $blueprint, Fluent $command)
{
$table = $this->wrapTable($blueprint);
$on = $this->wrapTable($command->on);
// We need to prepare several of the elements of the foreign key definition
// before we can create the SQL, such as wrapping the tables and convert
// an array of columns to comma-delimited strings for the SQL queries.
$columns = $this->columnize($command->columns);
$onColumns = $this->columnize((array) $command->references);
// Aucune utilité d'avoir le nom du schéma dans le nom de la contrainte Foreign
$schemaTable = explode(".", $table);
if (count($schemaTable) > 1)
{
$command->index = str_replace($schemaTable[0]."_", "", $command->index);
}
$sql = "alter table {$table} add constraint {$command->index} ";
$sql .= "foreign key ({$columns}) references {$on} ({$onColumns})";
// Once we have the basic foreign key creation statement constructed we can
// build out the syntax for what should happen on an update or delete of
// the affected columns, which will get something like "cascade", etc.
if ( ! is_null($command->onDelete))
{
$sql .= " on delete {$command->onDelete}";
}
if ( ! is_null($command->onUpdate))
{
$sql .= " on update {$command->onUpdate}";
}
return $sql;
}
/**
* Compile a unique key command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileUnique(Blueprint $blueprint, Fluent $command)
{
$table = $this->wrapTable($blueprint);
$columns = $this->columnize($command->columns);
// Aucune utilité d'avoir le nom du schéma dans le nom de la contrainte Unique
$schemaTable = explode(".", $table);
if (count($schemaTable) > 1)
{
$command->index = str_replace($schemaTable[0]."_", "", $command->index);
}
return "alter table {$table} add constraint {$command->index} unique({$columns})";
}
/**
* Compile a plain index key command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileIndex(Blueprint $blueprint, Fluent $command)
{
$table = $this->wrapTable($blueprint);
$columns = $this->columnize($command->columns);
// Aucune utilité d'avoir le nom du schéma dans le nom de la contrainte Index
$schemaTable = explode(".", $table);
if (count($schemaTable) > 1)
{
$command->index = str_replace($schemaTable[0]."_", "", $command->index);
}
$sql = "create index {$command->index}";
if ($command->indexSystem)
{
$sql .= " for system name {$command->indexSystem}";
}
$sql .= " on {$table}($columns)";
//return "create index {$command->index} for system name on {$table}($columns)";
return $sql;
}
/**
* Compile a drop table command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileDrop(Blueprint $blueprint, Fluent $command)
{
return 'drop table '.$this->wrapTable($blueprint);
}
/**
* Compile a drop table (if exists) command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
{
return 'drop table if exists '.$this->wrapTable($blueprint);
}
/**
* Compile a drop column command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileDropColumn(Blueprint $blueprint, Fluent $command)
{
$columns = $this->prefixArray('drop', $this->wrapArray($command->columns));
$table = $this->wrapTable($blueprint);
return 'alter table '.$table.' '.implode(', ', $columns);
}
/**
* Compile a drop primary key command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
{
return 'alter table '.$this->wrapTable($blueprint).' drop primary key';
}
/**
* Compile a drop unique key command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileDropUnique(Blueprint $blueprint, Fluent $command)
{
$table = $this->wrapTable($blueprint);
// Aucune utilité d'avoir le nom du schéma dans le nom de la contrainte Unique
$schemaTable = explode(".", $table);
if (count($schemaTable) > 1)
{
$command->index = str_replace($schemaTable[0]."_", "", $command->index);
}
return "alter table {$table} drop index {$command->index}";
}
/**
* Compile a drop index command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileDropIndex(Blueprint $blueprint, Fluent $command)
{
$table = $this->wrapTable($blueprint);
// Aucune utilité d'avoir le nom du schéma dans le nom de la contrainte Index
$schemaTable = explode(".", $table);
if (count($schemaTable) > 1)
{
$command->index = str_replace($schemaTable[0]."_", "", $command->index);
}
return "alter table {$table} drop index {$command->index}";
}
/**
* Compile a drop foreign key command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileDropForeign(Blueprint $blueprint, Fluent $command)
{
$table = $this->wrapTable($blueprint);
// Aucune utilité d'avoir le nom du schéma dans le nom de la contrainte Foreign
$schemaTable = explode(".", $table);
if (count($schemaTable) > 1)
{
$command->index = str_replace($schemaTable[0]."_", "", $command->index);
}
return "alter table {$table} drop foreign key {$command->index}";
}
/**
* Compile a rename table command.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $command
* @return string
*/
public function compileRename(Blueprint $blueprint, Fluent $command)
{
$from = $this->wrapTable($blueprint);
return "rename table {$from} to ".$this->wrapTable($command->to);
}
/**
* Create the column definition for a char type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeChar(Fluent $column)
{
return "char({$column->length})";
}
/**
* Create the column definition for a string type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeString(Fluent $column)
{
return "varchar({$column->length})";
}
/**
* Create the column definition for a text type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeText(Fluent $column)
{
return 'text';
}
/**
* Create the column definition for a medium text type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeMediumText(Fluent $column)
{
return 'mediumtext';
}
/**
* Create the column definition for a long text type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeLongText(Fluent $column)
{
return 'longtext';
}
/**
* Create the column definition for a big integer type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeBigInteger(Fluent $column)
{
return 'bigint';
}
/**
* Create the column definition for a integer type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeInteger(Fluent $column)
{
return 'int';
}
/**
* Create the column definition for a small integer type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeSmallInteger(Fluent $column)
{
return 'smallint';
}
/**
* Create the column definition for a numeric type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeNumeric(Fluent $column)
{
return "numeric({$column->total}, {$column->places})";
}
/**
* Create the column definition for a float type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeFloat(Fluent $column)
{
return "float({$column->total}, {$column->places})";
}
/**
* Create the column definition for a double type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeDouble(Fluent $column)
{
if ($column->total && $column->places)
{
return "double({$column->total}, {$column->places})";
}
else
{
return 'double';
}
}
/**
* Create the column definition for a decimal type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeDecimal(Fluent $column)
{
return "decimal({$column->total}, {$column->places})";
}
/**
* Create the column definition for a boolean type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeBoolean(Fluent $column)
{
return 'smallint constraint '.$column->type.'_'.$column->prefix.'_'.$column->name.' check('.$column->name.' in(0,1))'.(is_null($column->default) ? ' default 0' : '');
}
/**
* Create the column definition for an enum type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeEnum(Fluent $column)
{
return "enum('".implode("', '", $column->allowed)."')";
}
/**
* Create the column definition for a date type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeDate(Fluent $column)
{
if ( ! $column->nullable)
return 'date default current_date';
return 'date';
}
/**
* Create the column definition for a date-time type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeDateTime(Fluent $column)
{
return 'datetime';
}
/**
* Create the column definition for a time type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeTime(Fluent $column)
{
if ( ! $column->nullable)
return 'time default current_time';
return 'time';
}
/**
* Create the column definition for a timestamp type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeTimestamp(Fluent $column)
{
if ( ! $column->nullable)
return 'timestamp default current_timestamp';
return 'timestamp';
}
/**
* Create the column definition for a binary type.
*
* @param \Illuminate\Support\Fluent $column
* @return string
*/
protected function typeBinary(Fluent $column)
{
return 'blob';
}
/**
* Get the SQL for a nullable column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyNullable(Blueprint $blueprint, Fluent $column)
{
return $column->nullable ? '' : ' not null';
}
/**
* Get the SQL for a default column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyDefault(Blueprint $blueprint, Fluent $column)
{
if ( ! is_null($column->default))
{
return " default ".$this->getDefaultValue($column->default);
}
}
/**
* Get the SQL for an auto-increment column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
{
if (in_array($column->type, $this->serials) && $column->autoIncrement)
{
return ' as identity';
}
}
/**
* Get the SQL for an "before" column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyBefore(Blueprint $blueprint, Fluent $column)
{
if ( ! is_null($column->before))
{
return ' before '.$this->wrap($column->before);
}
}
/**
* Get the SQL for an "for column" column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyForColumn(Blueprint $blueprint, Fluent $column)
{
if ( ! is_null($column->forColumn))
{
return ' for column '.$this->wrap($column->forColumn);
}
}
/**
* Get the SQL for a "generated" column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyGenerated(Blueprint $blueprint, Fluent $column)
{
if ( ! is_null($column->generated))
{
return ' generated '.($column->generated === true ? 'always' : $this->wrap($column->generated));
}
}
/**
* Get the SQL for a "startWith" column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyStartWith(Blueprint $blueprint, Fluent $column)
{
if ( ! is_null($column->startWith))
{
return ' (start with '.$column->startWith.')';
}
}
/**
* Get the SQL for an "implicitly hidden" column modifier.
*
* @param \Illuminate\Database\Schema\Blueprint $blueprint
* @param \Illuminate\Support\Fluent $column
* @return string|null
*/
protected function modifyImplicitlyHidden(Blueprint $blueprint, Fluent $column)
{
if ( ! is_null($column->implicitlyHidden))
{
return ' implicitly hidden';
}
}
/**
* Format a value so that it can be used in "default" clauses.
*
* @param mixed $value
* @return string
*/
protected function getDefaultValue($value)
{
if ($value instanceof Expression
|| is_bool($value)
|| is_numeric($value)) return $value;
return "'".strval($value)."'";
}
}

118
src/config/config.php Normal file
View File

@ -0,0 +1,118 @@
<?php
/*
|--------------------------------------------------------------------------
| DB2 Config
|--------------------------------------------------------------------------
Valeurs définies pour le niveau d'isolation, pour PDO (mot clé "CMT" ou "CommitMode" dans le DSN) :
0 = Commit immediate (*NONE)
1 = Read committed (*CS)
2 = Read uncommitted (*CHG)
3 = Repeatable read (*ALL)
4 = Serializable (*RR)
* i5_naming:
0 = "sql" (as in schema.table)
1 = "system" (as in schema/table)
* i5_date_fmt:
0 = yy/dd (*JUL)
1 = mm/dd/yy (*MDY)
2 = dd/mm/yy (*DMY)
3 = yy/mm/dd (*YMD)
4 = mm/dd/yyyy (*USA)
5 = yyyy-mm-dd (*ISO)
6 = dd.mm.yyyy (*EUR)
7 = yyyy-mm-dd (*JIS)
* i5_date_sep:
0 = "/" (forward slash)
1 = "-" (dash)
2 = "." (period)
3 = "," (comma)
4 = " " (blank)
* i5_decimal_sep:
0 = "." (period)
1 = "," (comma)
* i5_time_fmt:
0 = hh:mm:ss (*HMS)
1 = hh:mm AM/PM (*USA)
2 = hh.mm.ss (*ISO)
3 = hh.mm.ss (*EUR)
4 = hh:mm:ss (*JIS)
* i5_time_sep:
0 = ":" (colon)
1 = "." (period)
2 = "," (comma)
3 = " " (blank)
* PDO::ATTR_CASE:
PDO::CASE_LOWER
PDO::CASE_UPPER
PDO::CASE_NATURAL
*/
return [
'connections' => [
'odbc' => [
'driver' => 'odbc',
'host' => '',
'database' => '',
'username' => '',
'password' => '',
'charset' => 'utf8',
'ccsid' => 1208,
'prefix' => '',
'schema' => '',
'i5_libl' => '',
'i5_lib' => '',
'i5_commit' => 0,
'i5_naming' => 0,
'i5_date_fmt' => 5,
'i5_date_sep' => 0,
'i5_decimal_sep' => 0,
'i5_time_fmt' => 0,
'i5_time_sep' => 0,
'options' => [
PDO::ATTR_CASE => PDO::CASE_LOWER,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_PERSISTENT => false
]
],
'ibm' => [
'driver' => 'ibm',
'host' => '',
'database' => '',
'username' => '',
'password' => '',
'charset' => 'utf8',
'ccsid' => 1208,
'prefix' => '',
'schema' => '',
'i5_libl' => '',
'i5_lib' => '',
'i5_commit' => 0,
'i5_naming' => 0,
'i5_date_fmt' => 5,
'i5_date_sep' => 0,
'i5_decimal_sep' => 0,
'i5_time_fmt' => 0,
'i5_time_sep' => 0,
'options' => [
PDO::ATTR_CASE => PDO::CASE_LOWER,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_PERSISTENT => false
]
],
]
];