Migration automatique de table START_C

This commit is contained in:
Jérémy Munsch 2023-08-14 13:36:18 +02:00
parent 97623ce240
commit a6de982ef1
No known key found for this signature in database
GPG key ID: 18361AF3BFEC0FEC
2 changed files with 229 additions and 0 deletions

View file

@ -63,6 +63,18 @@ return [
]) : [],
],
'oracle' => [
'driver' => 'oracle',
'host' => env('DB_OCI_HOST', ''),
'port' => env('DB_OCI_PORT', '1521'),
'database' => env('DB_OCI_DATABASE', ''),
'username' => env('DB_OCI_USERNAME', ''),
'password' => env('DB_OCI_PASSWORD', ''),
'charset' => env('DB_OCI_CHARSET', 'AL32UTF8'),
'prefix' => env('DB_OCI_PREFIX', ''),
'prefix_schema' => env('DB_OCI_SCHEMA_PREFIX', ''),
],
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),

View file

@ -0,0 +1,217 @@
<?php
use Carbon\Carbon;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* StartC table prefix
*
* @var string
*/
private $tablePrefix = 'STARTC';
/**
* StartC table to migrate
*
* @var string[]
*/
private $tableList = [
'FAMILLE', 'CERTIFICATION',
'RAYON', 'RESEAU',
'SECTEUR', 'SOURCE',
'VEILLE_PROD', 'VEILLE_PROD_COMM',
];
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
foreach ($this->tableList as $tableName) {
$header = $this->fetOciTableHeader($tableName);
$this->createTable(
"{$this->tablePrefix}_{$tableName}",
$header
);
$content = $this->fetchOciTableContent($tableName, $header);
foreach ($content as $row) {
DB::table("{$this->tablePrefix}_{$tableName}")->insert((array)$row);
}
}
}
/**
* Reverse the migrations.
*
* @return void
* @throws \Error Wont rollback.
*/
public function down(): void
{
throw new \Error('Wont rollback');
}
/**
* Create table in SQL
*
* @param string $tableName
* @param array<object> $tableColumns With name, type, size.
* @return void
*/
private function createTable(string $tableName, array $tableColumns)
{
Schema::dropIfExists($tableName);
Schema::create($tableName, function (Blueprint $table) use ($tableColumns) {
foreach ($tableColumns as $tableColumn) {
$tableComment = "{$tableColumn->name} {$tableColumn->type} {$tableColumn->size}";
switch ($tableColumn->type) {
case 'NUMBER':
$table->bigInteger($tableColumn->name)
->nullable()->comment($tableComment);
break;
case 'VARCHAR2':
case 'CHAR':
$table->string($tableColumn->name, $tableColumn->size)
->nullable()->comment($tableComment);
break;
case 'DATE':
$table->dateTime($tableColumn->name)
->nullable()->comment($tableComment);
break;
default:
throw new Error("Unhandled type {$tableColumn->type}");
}
}
});
}
/**
* Oci table header
*
* @param string $tableName
* @return array<object> with name, type, size
* @throws \Error If connection or query fails.
*/
private function fetOciTableHeader(string $tableName): array
{
$tableName = "{$this->tablePrefix}_{$tableName}";
$conn = $this->getOciConnection();
// Prepare the statement.
$stid = oci_parse($conn, "SELECT * FROM {$tableName}");
if (!$stid) {
$e = oci_error($conn);
throw new \Error(htmlentities($e['message'], ENT_QUOTES));
}
// Use OCI_DESCRIBE_ONLY if not fetching rows.
oci_execute($stid, OCI_DESCRIBE_ONLY);
if (!$stid) {
$e = oci_error($conn);
throw new \Error(htmlentities($e['message'], ENT_QUOTES));
}
$ncols = oci_num_fields($stid);
$out = [];
for ($i = 1; $i <= $ncols; $i++) {
$column_name = oci_field_name($stid, $i);
$column_type = oci_field_type($stid, $i);
$column_size = oci_field_size($stid, $i);
$out[] = (object)[
'name' => $column_name,
'type' => $column_type,
'size' => $column_size
];
}
oci_free_statement($stid);
oci_close($conn);
return $out;
}
/**
* Oci table content
*
* @param string $tableName Table name.
* @param array<object> $header With name, type,size.
* @return array<object> With DB content.
* @throws \Error If connection or query fails.
*/
private function fetchOciTableContent(string $tableName, array $header): array
{
$out = [];
$tableName = "{$this->tablePrefix}_{$tableName}";
$conn = $this->getOciConnection();
// Prepare the statement.
$stid = oci_parse($conn, "SELECT * FROM {$tableName}");
if (!$stid) {
$e = oci_error($conn);
throw new \Error(htmlentities($e['message'], ENT_QUOTES));
}
$r = oci_execute($stid);
if (!$stid) {
$e = oci_error($conn);
throw new \Error(htmlentities($e['message'], ENT_QUOTES));
}
while ($row = oci_fetch_array($stid, OCI_ASSOC + OCI_RETURN_NULLS)) {
$outRow = [];
foreach ($row as $k => $item) {
/** @var string */
$type = collect($header)->where('name', $k)->firstOrFail()->type;
if ($type === 'DATE' and $item !== null) {
$item = $this->tryToParseCarbon($item);
}
$outRow[$k] = $item;
}
$out[] = (object)$outRow;
}
oci_free_statement($stid);
oci_close($conn);
return $out;
}
/**
* get Oci connection
*
* @return resource oci8 connection resource
* @throws \Error If connection fails.
*/
private function getOciConnection()
{
$conn = oci_connect('system', 'secret', 'localhost/XE');
if (!$conn) {
$e = oci_error();
throw new \Error(htmlentities($e['message'], ENT_QUOTES));
}
return $conn;
}
/**
* Try to parse freaking Start coq dates
*
* @param string $date
* @return \Carbon\Carbon
* @throws \Carbon\Exceptions\InvalidFormatException In case of failure.
*/
private function tryToParseCarbon(string $date): Carbon
{
return Carbon::parse($date);
}
};