seeder db
All checks were successful
All checks were successful
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -20,4 +20,4 @@ yarn-error.log
|
||||
/public/modules/*
|
||||
.qodo
|
||||
.camel-jbang
|
||||
dump/
|
||||
dump/
|
||||
|
||||
201
database/seeders/InitialDataSeeder.php
Normal file
201
database/seeders/InitialDataSeeder.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class InitialDataSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$sqlPath = base_path('db/kulakposmysql.sql');
|
||||
|
||||
if (!File::exists($sqlPath)) {
|
||||
$this->command->error("SQL file not found at: {$sqlPath}");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->command->info("Starting initial data import from: {$sqlPath}");
|
||||
|
||||
// Disable foreign key checks for PostgreSQL
|
||||
if (DB::getDriverName() === 'pgsql') {
|
||||
DB::statement("SET session_replication_role = 'replica';");
|
||||
} else {
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
|
||||
}
|
||||
|
||||
$handle = fopen($sqlPath, "r");
|
||||
if ($handle) {
|
||||
$currentTable = null;
|
||||
$insertCount = 0;
|
||||
$tableColumnMap = [];
|
||||
|
||||
while (($line = fgets($handle)) !== false) {
|
||||
$line = trim($line);
|
||||
|
||||
// Detect CREATE TABLE statement to extract column order
|
||||
if (preg_match('/^CREATE TABLE `(.+?)`/i', $line, $matches)) {
|
||||
$currentTable = $matches[1];
|
||||
$tableColumnMap[$currentTable] = [];
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we are inside a CREATE TABLE block, look for column definitions
|
||||
if ($currentTable && preg_match('/^\s*`(.+?)`/i', $line, $colMatches)) {
|
||||
$tableColumnMap[$currentTable][] = $colMatches[1];
|
||||
}
|
||||
|
||||
// End of CREATE TABLE block
|
||||
if ($currentTable && strpos($line, ') ENGINE') !== false) {
|
||||
$currentTable = null;
|
||||
}
|
||||
|
||||
// Detect INSERT INTO statement
|
||||
if (preg_match('/^INSERT INTO `(.+?)` VALUES\s*\((.*)\);$/i', $line, $matches)) {
|
||||
$tableName = $matches[1];
|
||||
$valuesStr = $matches[2];
|
||||
|
||||
$values = $this->parseValues($valuesStr);
|
||||
$sqlColumns = $tableColumnMap[$tableName] ?? [];
|
||||
|
||||
try {
|
||||
$data = $this->mapValuesToTable($tableName, $values, $sqlColumns);
|
||||
if (!empty($data)) {
|
||||
DB::table($tableName)->insert($data);
|
||||
$insertCount++;
|
||||
|
||||
if ($insertCount % 100 === 0) {
|
||||
$this->command->info("Imported {$insertCount} records...");
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->command->error("Error inserting into {$tableName}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose($handle);
|
||||
$this->command->info("Finished! Total records imported: {$insertCount}");
|
||||
}
|
||||
|
||||
// Re-enable foreign key checks
|
||||
if (DB::getDriverName() === 'pgsql') {
|
||||
DB::statement("SET session_replication_role = 'origin';");
|
||||
// Update sequences for PostgreSQL
|
||||
$this->updatePostgresSequences();
|
||||
} else {
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update PostgreSQL sequences so they don't clash with imported IDs.
|
||||
*/
|
||||
private function updatePostgresSequences()
|
||||
{
|
||||
$this->command->info("Updating PostgreSQL sequences...");
|
||||
$tables = DB::select("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'");
|
||||
foreach ($tables as $table) {
|
||||
$tableName = $table->table_name;
|
||||
try {
|
||||
$maxId = DB::table($tableName)->max('id');
|
||||
if ($maxId) {
|
||||
$seqName = "{$tableName}_id_seq";
|
||||
// Check if sequence exists
|
||||
$seqExists = DB::select("SELECT 1 FROM pg_class WHERE relname = ?", [$seqName]);
|
||||
if ($seqExists) {
|
||||
DB::statement("SELECT setval(?, ?, true)", [$seqName, $maxId]);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// Ignore if table doesn't have id column or sequence
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic parser for MySQL values string: (val1, val2, ...)
|
||||
*/
|
||||
private function parseValues($str)
|
||||
{
|
||||
$values = [];
|
||||
$i = 0;
|
||||
$len = strlen($str);
|
||||
$current = '';
|
||||
$inString = false;
|
||||
$stringChar = '';
|
||||
|
||||
while ($i < $len) {
|
||||
$char = $str[$i];
|
||||
|
||||
if ($inString) {
|
||||
if ($char === $stringChar && ($i === 0 || $str[$i - 1] !== '\\')) {
|
||||
$inString = false;
|
||||
$values[] = str_replace(['\\\'', '\\"'], ["'", '"'], $current);
|
||||
$current = '';
|
||||
} else {
|
||||
$current .= $char;
|
||||
}
|
||||
} else {
|
||||
if ($char === "'" || $char === '"') {
|
||||
$inString = true;
|
||||
$stringChar = $char;
|
||||
} elseif ($char === ',') {
|
||||
$val = trim($current);
|
||||
if ($val !== '') {
|
||||
$values[] = $this->castValue($val);
|
||||
}
|
||||
$current = '';
|
||||
} else {
|
||||
$current .= $char;
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
// Last value
|
||||
$val = trim($current);
|
||||
if ($val !== '') {
|
||||
$values[] = $this->castValue($val);
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
private function castValue($val)
|
||||
{
|
||||
if (strtoupper($val) === 'NULL') return null;
|
||||
if (is_numeric($val) && (strpos($val, '0') !== 0 || $val === '0')) {
|
||||
return $val + 0; // Convert to int or float
|
||||
}
|
||||
return trim($val, "'\"");
|
||||
}
|
||||
|
||||
/**
|
||||
* Map numerical values to column names based on SQL dump schema and filter by DB schema.
|
||||
*/
|
||||
private function mapValuesToTable($table, $values, $sqlColumns)
|
||||
{
|
||||
if (empty($sqlColumns) || count($sqlColumns) !== count($values)) {
|
||||
return []; // Can't reliably map
|
||||
}
|
||||
|
||||
// Combine using SQL column names
|
||||
$mapped = array_combine($sqlColumns, $values);
|
||||
|
||||
// Get actual columns in the database
|
||||
static $dbColumnsCache = [];
|
||||
if (!isset($dbColumnsCache[$table])) {
|
||||
$dbColumnsCache[$table] = DB::getSchemaBuilder()->getColumnListing($table);
|
||||
}
|
||||
$dbColumns = $dbColumnsCache[$table];
|
||||
|
||||
// Filter out columns that don't exist in the current DB
|
||||
return array_intersect_key($mapped, array_flip($dbColumns));
|
||||
}
|
||||
}
|
||||
2842
db/kulakposmysql.sql
Normal file
2842
db/kulakposmysql.sql
Normal file
File diff suppressed because one or more lines are too long
@@ -176,6 +176,7 @@ fi
|
||||
if [ "$AUTO_MIGRATE" = "true" ] || [ "$APP_ENV" != "production" ]; then
|
||||
echo "Running migrations..."
|
||||
php artisan migrate --force
|
||||
php artisan db:seed --class=InitialDataSeeder
|
||||
fi
|
||||
|
||||
echo "========================================"
|
||||
|
||||
Reference in New Issue
Block a user