Skip to content

Commit 5638fc7

Browse files
committed
feat: ability to set loader connection
1 parent 942af6a commit 5638fc7

File tree

5 files changed

+126
-68
lines changed

5 files changed

+126
-68
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,25 @@ Yajra\SQLLoader\CsvFile::make(database_path('files/users.csv'), 'w')
159159
160160
#### Loading CSV File with Headers
161161
162+
Load users from `oracle` to `backup` database connection.
163+
162164
```php
163165
$loader->inFile(database_path('files/users.csv'))
164166
->withHeaders()
167+
->mode(Yajra\SQLLoader\Mode::TRUNCATE)
168+
->connection('backup')
165169
->into('users')
166170
->execute();
167171
```
168172
173+
### Connection
174+
175+
You can set the connection name to use for the SQL Loader command using the `connection` method.
176+
177+
```php
178+
$loader->connection('oracle');
179+
```
180+
169181
### Disk
170182
171183
You can set the disk to use for the control file using the `disk` method.

src/SQLLoader.php

Lines changed: 80 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,16 @@ class SQLLoader
2222
/** @var TableDefinition[] */
2323
public array $tables = [];
2424

25-
protected array $defaultColumns = [];
26-
2725
public Mode $mode = Mode::APPEND;
2826

2927
public ?string $controlFile = null;
3028

29+
public array $beginData = [];
30+
31+
public ?string $connection = null;
32+
33+
protected array $defaultColumns = [];
34+
3135
protected ?string $disk = null;
3236

3337
protected ?string $logPath = null;
@@ -38,42 +42,12 @@ class SQLLoader
3842

3943
protected string $logs = '';
4044

41-
public array $beginData = [];
42-
4345
protected string $dateFormat = 'YYYY-MM-DD"T"HH24:MI:SS."000000Z"';
4446

4547
public function __construct(public array $options = [])
4648
{
4749
}
4850

49-
/**
50-
* Set SQL Loader options.
51-
*/
52-
public function options(array $options): static
53-
{
54-
$this->options = $options;
55-
56-
return $this;
57-
}
58-
59-
/**
60-
* Define input file to load data from.
61-
*/
62-
public function inFile(
63-
string $path,
64-
?string $badFile = null,
65-
?string $discardFile = null,
66-
?string $discardMax = null
67-
): static {
68-
if (! File::exists($path) && $path !== '*') {
69-
throw new InvalidArgumentException("File [{$path}] does not exist.");
70-
}
71-
72-
$this->inputFiles[] = new InputFile($path, $badFile, $discardFile, $discardMax);
73-
74-
return $this;
75-
}
76-
7751
/**
7852
* Define mode to use.
7953
*/
@@ -114,6 +88,49 @@ public function into(
11488
return $this;
11589
}
11690

91+
protected function buildDefaultColumns(string $table, array $columns): array
92+
{
93+
$columns = $this->defaultColumns;
94+
$schemaColumns = collect(Schema::connection(config('sql-loader.connection'))->getColumns($table));
95+
96+
$dates = $schemaColumns->filter(fn ($column) => in_array($column['type'], [
97+
'DATE',
98+
'DATETIME',
99+
'TIMESTAMP',
100+
'TIMESTAMP(6)',
101+
]))->pluck('name')->toArray();
102+
103+
$booleans = $schemaColumns->filter(fn ($column) => $column['nullable'] === 'N' && $column['type'] === 'CHAR')->pluck('name')->toArray();
104+
105+
foreach ($columns as $key => $column) {
106+
$column = strtoupper((string) $column);
107+
108+
if (in_array($column, $dates)) {
109+
$columns[$key] = "\"$column\" DATE";
110+
111+
continue;
112+
}
113+
114+
if (in_array($column, $booleans)) {
115+
$default = $schemaColumns->where('name', $column)->first()['default'];
116+
$columns[$key] = "\"$column\" \"DECODE(:$column, '', $default, :$column)\"";
117+
118+
continue;
119+
}
120+
121+
$columns[$key] = "\"$column\"";
122+
}
123+
124+
return $columns;
125+
}
126+
127+
public function connection(string $connection): static
128+
{
129+
$this->connection = $connection;
130+
131+
return $this;
132+
}
133+
117134
/**
118135
* Execute SQL Loader command.
119136
*/
@@ -209,7 +226,7 @@ public function buildControlFile(): string
209226
*/
210227
protected function buildTNS(): string
211228
{
212-
return TnsBuilder::make();
229+
return TnsBuilder::make($this->getConnection());
213230
}
214231

215232
/**
@@ -385,6 +402,24 @@ public function beginData(array $data): static
385402
return $this;
386403
}
387404

405+
/**
406+
* Define input file to load data from.
407+
*/
408+
public function inFile(
409+
string $path,
410+
?string $badFile = null,
411+
?string $discardFile = null,
412+
?string $discardMax = null
413+
): static {
414+
if (! File::exists($path) && $path !== '*') {
415+
throw new InvalidArgumentException("File [{$path}] does not exist.");
416+
}
417+
418+
$this->inputFiles[] = new InputFile($path, $badFile, $discardFile, $discardMax);
419+
420+
return $this;
421+
}
422+
388423
public function withHeaders(): static
389424
{
390425
$this->options(['skip=1']);
@@ -394,46 +429,25 @@ public function withHeaders(): static
394429
return $this;
395430
}
396431

397-
public function dateFormat(string $format): static
432+
/**
433+
* Set SQL Loader options.
434+
*/
435+
public function options(array $options): static
398436
{
399-
$this->dateFormat = $format;
437+
$this->options = $options;
400438

401439
return $this;
402440
}
403441

404-
protected function buildDefaultColumns(string $table, array $columns): array
442+
public function dateFormat(string $format): static
405443
{
406-
$columns = $this->defaultColumns;
407-
$schemaColumns = collect(Schema::connection(config('sql-loader.connection'))->getColumns($table));
408-
409-
$dates = $schemaColumns->filter(fn ($column) => in_array($column['type'], [
410-
'DATE',
411-
'DATETIME',
412-
'TIMESTAMP',
413-
'TIMESTAMP(6)',
414-
]))->pluck('name')->toArray();
415-
416-
$booleans = $schemaColumns->filter(fn ($column) => $column['nullable'] === 'N' && $column['type'] === 'CHAR')->pluck('name')->toArray();
417-
418-
foreach ($columns as $key => $column) {
419-
$column = strtoupper((string) $column);
420-
421-
if (in_array($column, $dates)) {
422-
$columns[$key] = "\"$column\" DATE";
423-
424-
continue;
425-
}
426-
427-
if (in_array($column, $booleans)) {
428-
$default = $schemaColumns->where('name', $column)->first()['default'];
429-
$columns[$key] = "\"$column\" \"DECODE(:$column, '', $default, :$column)\"";
430-
431-
continue;
432-
}
444+
$this->dateFormat = $format;
433445

434-
$columns[$key] = "\"$column\"";
435-
}
446+
return $this;
447+
}
436448

437-
return $columns;
449+
public function getConnection(): string
450+
{
451+
return $this->connection ?? config('sql-loader.connection', 'oracle');
438452
}
439453
}

src/TnsBuilder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
class TnsBuilder
88
{
9-
public static function make(): string
9+
public static function make(?string $connection = null): string
1010
{
11-
$connection = config('sql-loader.connection', 'oracle');
11+
$connection ??= config('sql-loader.connection', 'oracle');
1212
$username = config('database.connections.'.$connection.'.username');
1313
$password = config('database.connections.'.$connection.'.password');
1414
$host = config('database.connections.'.$connection.'.host');

tests/Feature/SQLLoaderTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,25 @@
100100
return str_contains((string) $process->command, "sqlldr userid={$tns} control={$controlFile}");
101101
});
102102
});
103+
104+
test('it can use another database connection', function () {
105+
Process::fake();
106+
107+
$loader = new SQLLoader(['skip=1']);
108+
$loader->inFile(__DIR__.'/../data/users.dat')
109+
->as('users.ctl')
110+
->connection('mysql')
111+
->into('users', ['id', 'name', 'email'])
112+
->execute();
113+
114+
Process::assertRan(function (PendingProcess $process, ProcessResult $result) {
115+
$username = config('database.connections.mysql.username');
116+
$password = config('database.connections.mysql.password');
117+
$host = config('database.connections.mysql.host');
118+
$port = config('database.connections.mysql.port');
119+
$database = config('database.connections.mysql.database');
120+
$controlFile = storage_path('app/users.ctl');
121+
122+
return str_contains((string) $process->command, "sqlldr userid={$username}/{$password}@{$host}:{$port}/{$database} control={$controlFile}");
123+
});
124+
});

tests/Feature/TnsBuilderTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,13 @@
1313

1414
assertEquals("$username/$password@$host:$port/$database", TnsBuilder::make());
1515
});
16+
17+
test('it accepts a connection', function () {
18+
$username = config('database.connections.mysql.username');
19+
$password = config('database.connections.mysql.password');
20+
$host = config('database.connections.mysql.host');
21+
$port = config('database.connections.mysql.port');
22+
$database = config('database.connections.mysql.database');
23+
24+
assertEquals("$username/$password@$host:$port/$database", TnsBuilder::make('mysql'));
25+
});

0 commit comments

Comments
 (0)