55namespace OpenStatSpec \Spss ;
66
77use OpenStatSpec \Core \DiagnosticCode ;
8+ use OpenStatSpec \Core \FidelityPolicy ;
89use OpenStatSpec \Core \UnsupportedOperation ;
910use OpenStatSpec \Sql \Connection ;
1011use OpenStatSpec \Sql \MySqlWideTableImporter ;
1112use OpenStatSpec \Sql \MySqlWideTableExporter ;
13+ use OpenStatSpec \Sql \OperationJournal ;
1214use OpenStatSpec \Sql \PostgreSqlWideTableExporter ;
1315use OpenStatSpec \Sql \PostgreSqlWideTableImporter ;
1416use OpenStatSpec \Sql \SqliteWideTableExporter ;
1517use OpenStatSpec \Sql \SqliteWideTableImporter ;
1618use PDO ;
19+ use Throwable ;
1720
1821final readonly class SpssAdapter
1922{
@@ -31,39 +34,62 @@ public function pdo(): PDO
3134 return $ this ->connection ->pdo ;
3235 }
3336
34- public function import (string $ sourcePath , string $ datasetName ): void
37+ public function import (string $ sourcePath , string $ datasetName ): SpssImportResult
3538 {
36- if (!in_array ($ this ->spssFormat ($ sourcePath ), ['sav ' , 'zsav ' ], true )) {
37- throw new UnsupportedOperation (
38- DiagnosticCode::UnsupportedSourceFormat,
39- 'This adapter profile supports SAV and ZSAV files only. ' ,
40- );
39+ $ journal = new OperationJournal ($ this ->connection ->pdo );
40+ $ operationId = $ journal ->start ('import ' , null , $ sourcePath );
41+ try {
42+ if (!in_array ($ this ->spssFormat ($ sourcePath ), ['sav ' , 'zsav ' ], true )) {
43+ throw new UnsupportedOperation (
44+ DiagnosticCode::UnsupportedSourceFormat,
45+ 'This adapter profile supports SAV and ZSAV files only. ' ,
46+ );
47+ }
48+ $ source = SpssSourceNormalizer ::normalize ($ this ->engine ->read ($ sourcePath ));
49+ match ($ this ->connection ->profile ->driverName ()) {
50+ 'pgsql ' => (new PostgreSqlWideTableImporter ($ this ->connection ->pdo ))->import ($ source , $ datasetName ),
51+ 'mysql ' => (new MySqlWideTableImporter ($ this ->connection ->pdo ))->import ($ source , $ datasetName ),
52+ default => (new SqliteWideTableImporter ($ this ->connection ->pdo ))->import ($ source , $ datasetName ),
53+ };
54+ $ diagnostics = [];
55+ $ journal ->succeed ($ operationId , $ datasetName , $ diagnostics );
56+
57+ return new SpssImportResult ($ operationId , $ datasetName , count ($ source ['data ' ]), $ diagnostics );
58+ } catch (Throwable $ exception ) {
59+ $ journal ->fail ($ operationId , null , $ exception );
60+ throw $ exception ;
4161 }
42- $ source = SpssSourceNormalizer ::normalize ($ this ->engine ->read ($ sourcePath ));
43- match ($ this ->connection ->profile ->driverName ()) {
44- 'pgsql ' => (new PostgreSqlWideTableImporter ($ this ->connection ->pdo ))->import ($ source , $ datasetName ),
45- 'mysql ' => (new MySqlWideTableImporter ($ this ->connection ->pdo ))->import ($ source , $ datasetName ),
46- default => (new SqliteWideTableImporter ($ this ->connection ->pdo ))->import ($ source , $ datasetName ),
47- };
4862 }
4963
50- public function export (string $ datasetName , string $ targetPath ): SpssExportResult
64+ /** @param list<string> $allowLoss */
65+ public function export (string $ datasetName , string $ targetPath , array $ allowLoss = []): SpssExportResult
5166 {
52- $ targetFormat = $ this ->spssFormat ($ targetPath );
53- if (!in_array ($ targetFormat , ['sav ' , 'zsav ' ], true )) {
54- throw new UnsupportedOperation (
55- DiagnosticCode::UnsupportedSourceFormat,
56- 'This adapter profile exports SAV and ZSAV files only. ' ,
57- );
58- }
59- $ export = match ($ this ->connection ->profile ->driverName ()) {
60- 'pgsql ' => (new PostgreSqlWideTableExporter ($ this ->connection ->pdo ))->export ($ datasetName , $ targetFormat ),
61- 'mysql ' => (new MySqlWideTableExporter ($ this ->connection ->pdo ))->export ($ datasetName , $ targetFormat ),
62- default => (new SqliteWideTableExporter ($ this ->connection ->pdo ))->export ($ datasetName , $ targetFormat ),
63- };
64- $ this ->engine ->write ($ targetPath , $ export ['dataset ' ]);
67+ $ journal = new OperationJournal ($ this ->connection ->pdo );
68+ $ operationId = $ journal ->start ('export ' , $ datasetName , $ targetPath , $ allowLoss );
69+ $ diagnostics = [];
70+ try {
71+ $ targetFormat = $ this ->spssFormat ($ targetPath );
72+ if (!in_array ($ targetFormat , ['sav ' , 'zsav ' ], true )) {
73+ throw new UnsupportedOperation (
74+ DiagnosticCode::UnsupportedSourceFormat,
75+ 'This adapter profile exports SAV and ZSAV files only. ' ,
76+ );
77+ }
78+ $ export = match ($ this ->connection ->profile ->driverName ()) {
79+ 'pgsql ' => (new PostgreSqlWideTableExporter ($ this ->connection ->pdo ))->export ($ datasetName , $ targetFormat ),
80+ 'mysql ' => (new MySqlWideTableExporter ($ this ->connection ->pdo ))->export ($ datasetName , $ targetFormat ),
81+ default => (new SqliteWideTableExporter ($ this ->connection ->pdo ))->export ($ datasetName , $ targetFormat ),
82+ };
83+ $ diagnostics = $ export ['diagnostics ' ];
84+ FidelityPolicy ::assertExportAllowed ($ diagnostics , $ allowLoss );
85+ $ this ->engine ->write ($ targetPath , $ export ['dataset ' ]);
86+ $ journal ->succeed ($ operationId , $ datasetName , $ diagnostics );
6587
66- return new SpssExportResult ($ datasetName , $ targetPath , $ export ['caseCount ' ], $ export ['diagnostics ' ]);
88+ return new SpssExportResult ($ operationId , $ datasetName , $ targetPath , $ export ['caseCount ' ], $ diagnostics , $ allowLoss );
89+ } catch (Throwable $ exception ) {
90+ $ journal ->fail ($ operationId , $ datasetName , $ exception , $ diagnostics );
91+ throw $ exception ;
92+ }
6793 }
6894
6995 private function spssFormat (string $ path ): string
0 commit comments