Skip to content

Commit 5e841d5

Browse files
committed
feat: import export bundle
1 parent 4bb3ad9 commit 5e841d5

20 files changed

+346
-70
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
3+
mdb_path=$1
4+
sqlite_path=$2
5+
id=$BASHPID
6+
tmp_dir="/tmp/mdb-convert/${id}"
7+
8+
test -f $sqlite_path && rm $sqlite_path
9+
10+
echo "Starting conversion in ${tmp_dir}"
11+
mkdir -p $tmp_dir
12+
mdb-schema $mdb_path sqlite > ${tmp_dir}/schema.sql
13+
mkdir -p ${tmp_dir}/sql
14+
for i in $( mdb-tables $mdb_path ); do mdb-export -D "%Y-%m-%d %H:%M:%S" -H -I sqlite $mdb_path $i > ${tmp_dir}/sql/$i.sql; done
15+
cat ${tmp_dir}/schema.sql | sqlite3 $sqlite_path
16+
for f in ${tmp_dir}/sql/* ; do (echo 'BEGIN;'; cat $f; echo 'COMMIT;') | sqlite3 $sqlite_path; done
17+
rm -rf $tmp_dir

components/ImportExportBundle/composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,8 @@
3434
"symfony/messenger": "Used to run job asynchronously"
3535
},
3636
"extra": {
37-
}
37+
},
38+
"bin": [
39+
"bin/mdb-to-sqlite.bash"
40+
]
3841
}

components/ImportExportBundle/src/bundle/Command/ExecuteWorkflowCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
4343
{
4444
$workflowIdentifier = $input->getArgument('identifier');
4545
$workflow = $this->workflowRegistry->getWorkflow($workflowIdentifier);
46-
$baseConfiguration = $workflow::getDefaultConfig();
46+
$baseConfiguration = $workflow->getDefaultConfig();
4747
if (!$baseConfiguration->isAvailable(WorkflowConfiguration::AVAILABILITY_CLI)) {
4848
throw new InvalidArgumentException(sprintf('Workflow %s is not available', $workflowIdentifier));
4949
}

components/ImportExportBundle/src/bundle/Resources/config/forms.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,8 @@ services:
4242
$filepathResolver: '@AlmaviaCX\Bundle\IbexaImportExport\Resolver\FilepathResolver'
4343
tags:
4444
- { name: form.type, alias: StreamWriterOptionsFormType }
45+
46+
AlmaviaCX\Bundle\IbexaImportExport\Reader\Mdb\MdbReaderOptionsFormType:
47+
parent: AlmaviaCX\Bundle\IbexaImportExport\Reader\File\FileReaderOptionsFormType
48+
tags:
49+
- { name: form.type, alias: MdbReaderOptionsFormType }

components/ImportExportBundle/src/bundle/Resources/config/workflow/component/reader.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,10 @@ services:
2828
parent: AlmaviaCX\Bundle\IbexaImportExport\Reader\File\AbstractFileReader
2929
tags:
3030
- { name: almaviacx.import_export.component, alias: reader.xml}
31+
32+
AlmaviaCX\Bundle\IbexaImportExport\Reader\Mdb\MdbReader:
33+
parent: AlmaviaCX\Bundle\IbexaImportExport\Reader\File\AbstractFileReader
34+
arguments:
35+
$converterPath: '%kernel.project_dir%/bin/mdb-to-sqlite.bash'
36+
tags:
37+
- { name: almaviacx.import_export.component, alias: reader.mdb}

components/ImportExportBundle/src/lib/Component/AbstractComponent.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ public function clean(): void
4949
{
5050
}
5151

52+
public function prepare(): void
53+
{
54+
}
55+
56+
public function finish(): void
57+
{
58+
}
59+
5260
public function setLogger(WorkflowLoggerInterface $logger): void
5361
{
5462
$this->logger = $logger;

components/ImportExportBundle/src/lib/Component/ComponentInterface.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,8 @@ public function getOptions(): ComponentOptions;
2727
public function clean(): void;
2828

2929
public function setLogger(WorkflowLoggerInterface $logger): void;
30+
31+
public function prepare(): void;
32+
33+
public function finish(): void;
3034
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AlmaviaCX\Bundle\IbexaImportExport\Item\Iterator;
6+
7+
use AlmaviaCX\Bundle\IbexaImportExport\Reader\ReaderIteratorInterface;
8+
use ArrayIterator;
9+
use Doctrine\DBAL\Connection;
10+
use Iterator;
11+
use SeekableIterator;
12+
13+
class DoctrineSeekableItemIterator implements ReaderIteratorInterface, SeekableIterator
14+
{
15+
public const DEFAULT_BATCH_SIZE = 25;
16+
protected Connection $connection;
17+
protected string $queryString;
18+
protected string $countQueryString;
19+
protected int $batchSize = self::DEFAULT_BATCH_SIZE;
20+
private ?Iterator $innerIterator;
21+
private int $position = 0;
22+
23+
public function __construct(
24+
Connection $connection,
25+
string $queryString,
26+
string $countQueryString,
27+
int $batchSize = self::DEFAULT_BATCH_SIZE
28+
) {
29+
$this->batchSize = $batchSize;
30+
$this->countQueryString = $countQueryString;
31+
$this->queryString = $queryString;
32+
$this->connection = $connection;
33+
}
34+
35+
private function fetch(): Iterator
36+
{
37+
$queryString = sprintf('%s LIMIT %d OFFSET %d', $this->queryString, $this->batchSize, $this->position);
38+
39+
return new ArrayIterator($this->connection->executeQuery($queryString)->fetchAllAssociative());
40+
}
41+
42+
private function initialize(): void
43+
{
44+
$this->position = 0;
45+
$this->innerIterator = $this->fetch();
46+
}
47+
48+
private function isInitialized(): bool
49+
{
50+
return isset($this->innerIterator);
51+
}
52+
53+
/**
54+
* @return mixed
55+
*/
56+
public function current()
57+
{
58+
if (!$this->isInitialized()) {
59+
$this->initialize();
60+
}
61+
62+
return $this->innerIterator->current();
63+
}
64+
65+
public function next(): void
66+
{
67+
if (!$this->isInitialized()) {
68+
$this->initialize();
69+
}
70+
++$this->position;
71+
$this->innerIterator->next();
72+
if (!$this->innerIterator->valid() && ($this->position % $this->batchSize) === 0) {
73+
$this->innerIterator = $this->fetch();
74+
}
75+
}
76+
77+
public function key(): mixed
78+
{
79+
return $this->position;
80+
}
81+
82+
public function valid(): bool
83+
{
84+
if (!$this->isInitialized()) {
85+
$this->initialize();
86+
}
87+
88+
return $this->innerIterator->valid();
89+
}
90+
91+
public function rewind(): void
92+
{
93+
$this->initialize();
94+
}
95+
96+
public function count(): int
97+
{
98+
return $this->connection->executeQuery($this->countQueryString)->fetchOne();
99+
}
100+
101+
public function seek($offset): void
102+
{
103+
$this->position = $offset;
104+
$this->innerIterator = $this->fetch();
105+
}
106+
}

components/ImportExportBundle/src/lib/Item/Iterator/ItemIterator.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
class ItemIterator extends AbstractReaderIterator
1111
{
1212
protected Iterator $innerIterator;
13-
protected IteratorItemTransformerInterface $itemTransformer;
13+
protected ?IteratorItemTransformerInterface $itemTransformer = null;
1414

1515
public function __construct(
1616
int $totalCount,
1717
Iterator $innerIterator,
18-
IteratorItemTransformerInterface $itemTransformer
18+
?IteratorItemTransformerInterface $itemTransformer = null
1919
) {
2020
$this->itemTransformer = $itemTransformer;
2121
$this->innerIterator = $innerIterator;
@@ -24,7 +24,12 @@ public function __construct(
2424

2525
public function current()
2626
{
27-
return ($this->itemTransformer)($this->innerIterator->current());
27+
$item = $this->innerIterator->current();
28+
if ($this->itemTransformer instanceof IteratorItemTransformerInterface) {
29+
return ($this->itemTransformer)($item);
30+
}
31+
32+
return $item;
2833
}
2934

3035
public function next(): void

components/ImportExportBundle/src/lib/Job/Job.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class Job
9494
*
9595
* @var Collection<JobRecord>
9696
*/
97-
protected Collection $records;
97+
protected ?Collection $records = null;
9898

9999
/**
100100
* @ORM\Column(type="text", nullable=true)

0 commit comments

Comments
 (0)