From 2d6bd8ff21e74127ac5d0d38fdf60925ec386bfe Mon Sep 17 00:00:00 2001 From: Mateusz Soroka Date: Mon, 9 Sep 2024 09:36:51 +0200 Subject: [PATCH] [Feature] Add SQL Data Source (#379) * Add SQL data source with connections select * Create sql data loader * Add sql format to file format selection * Update docs * Apply php-cs-fixer changes * Add doctrine dependencies * Replace executeQuery with execute to match doctrine dependency in SqlLoader * Add missing strict_types declaration in php files --------- Co-authored-by: msoroka --- composer.json | 3 +- doc/03_Configuration/01_Data_Sources.md | 39 +++++ doc/img/datasource_sql.png | Bin 0 -> 36196 bytes src/Controller/ConnectionController.php | 50 +++++++ .../Interpreter/SqlFileInterpreter.php | 22 +++ src/DataSource/Loader/SqlLoader.php | 137 ++++++++++++++++++ src/PimcoreDataImporterBundle.php | 2 + src/Resources/config/pimcore/routing.yml | 6 + src/Resources/config/services.yml | 11 ++ .../components/interpreter/sql.js | 36 +++++ .../configuration/components/loader/sql.js | 104 +++++++++++++ src/Resources/translations/admin.en.yml | 2 + 12 files changed, 411 insertions(+), 1 deletion(-) create mode 100644 doc/img/datasource_sql.png create mode 100644 src/Controller/ConnectionController.php create mode 100644 src/DataSource/Interpreter/SqlFileInterpreter.php create mode 100644 src/DataSource/Loader/SqlLoader.php create mode 100644 src/Resources/public/js/pimcore/configuration/components/interpreter/sql.js create mode 100644 src/Resources/public/js/pimcore/configuration/components/loader/sql.js diff --git a/composer.json b/composer.json index 0e10547c..daff1cd7 100644 --- a/composer.json +++ b/composer.json @@ -13,14 +13,15 @@ "prefer-stable": true, "minimum-stability": "dev", "require": { - "pimcore/compatibility-bridge-v10": "^1.0", "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", "ext-fileinfo": "*", "ext-json": "*", + "doctrine/dbal": "^2.12 || ^3.5", "dragonmantank/cron-expression": "^3.1", "league/flysystem-sftp-v3": "^3.0", "nesbot/carbon": "^2.27", "phpoffice/phpspreadsheet": "^1.24 || ^2.2", + "pimcore/compatibility-bridge-v10": "^1.0", "pimcore/data-hub": "^1.6", "pimcore/pimcore": "^10.6 || ^11.0", "symfony/mime": "^5.2 || ^6.2", diff --git a/doc/03_Configuration/01_Data_Sources.md b/doc/03_Configuration/01_Data_Sources.md index 6440830e..26276c11 100644 --- a/doc/03_Configuration/01_Data_Sources.md +++ b/doc/03_Configuration/01_Data_Sources.md @@ -52,3 +52,42 @@ The URL for the endpoint is: `http(s)://>/pimcore-datahub-import/ + +![Data Source SQL](../img/datasource_sql.png) + +Loads data from a defined doctrine connection. + +The SQL Data Loader uses [DBAL](https://www.doctrine-project.org/projects/dbal.html) to allow data to be +loaded from a SQL source. Connections to any database supported by DBAL will work provided they are +configured correctly inside of `database.yaml`. (Database configuration can be placed in any valid +Symfony config file, provided its in the correct format as can be seen in `database.yaml`). + +Example connection: +```yaml +doctrine: + dbal: + connections: + new_connection: + host: db + port: '3306' + user: sample_user + password: sample_password + dbname: sample_dbname + driver: any_supported_by_doctrine +``` + +For different drivers some additional configuration could be needed. + +##### Configuration Options: +- **Connection**: Connection from which data will be loaded +- **SELECT**: Valid SQL `SELECT` +- **FROM**: Valid SQL `FROM` +- **WHERE**: Valid SQL `WHERE` +- **GROUP BY**: Valid SQL `GROUP BY` + +Ensure to select **SQL** under File Format! \ No newline at end of file diff --git a/doc/img/datasource_sql.png b/doc/img/datasource_sql.png new file mode 100644 index 0000000000000000000000000000000000000000..70ce05afca4262e938ee25452e21db3defd33607 GIT binary patch literal 36196 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'doctrine.connections'); + + if (!is_array($connections)) { + throw new Exception('Doctrine connection not returned as array'); + } + + $mappedConnections = array_map(fn ($key, $value): array => [ + 'name' => $key, + 'value' => $value + ], array_keys($connections), $connections); + + return $this->json($mappedConnections); + } +} diff --git a/src/DataSource/Interpreter/SqlFileInterpreter.php b/src/DataSource/Interpreter/SqlFileInterpreter.php new file mode 100644 index 00000000..f5aec271 --- /dev/null +++ b/src/DataSource/Interpreter/SqlFileInterpreter.php @@ -0,0 +1,22 @@ +setUpConnection(); + $this->setUpImportFilePath(); + + $queryBuilder = $this->databaseConnection->createQueryBuilder(); + $queryBuilder->select($this->select) + ->from($this->from); + + if (!empty($this->where)) { + $queryBuilder->where($this->where); + } + + if (!empty($this->groupBy)) { + $queryBuilder->groupBy($this->groupBy); + } + + $result = $queryBuilder->execute()->fetchAllAssociative(); + + $filesystemLocal = new Filesystem(new LocalFilesystemAdapter('/')); + $stream = fopen('php://temp', 'r+'); + $resultAsJson = json_encode($result); + + fwrite($stream, $resultAsJson); + rewind($stream); + + $filesystemLocal->writeStream($this->importFilePath, $stream); + + return $this->importFilePath; + } + + public function cleanup(): void + { + $this->databaseConnection->close(); + + unlink($this->importFilePath); + } + + /** + * @throws InvalidConfigurationException + */ + public function setSettings(array $settings): void + { + if (empty($settings['connection'])) { + throw new InvalidConfigurationException('Empty connection.'); + } + $this->connection = $settings['connection']; + + if (empty($settings['select'])) { + throw new InvalidConfigurationException('Empty select.'); + } + $this->select = $settings['select']; + + if (empty($settings['from'])) { + throw new InvalidConfigurationException('Empty from.'); + } + $this->from = $settings['from']; + + $this->where = $settings['where']; + $this->groupBy = $settings['groupBy']; + } + + /** + * @throws InvalidConfigurationException + */ + private function setUpConnection(): void + { + $container = Pimcore::getContainer(); + $databaseConnection = null; + + if ($container instanceof Component\DependencyInjection\ContainerInterface) { + $databaseConnection = $container->get($this->connection); + } + + if (!$databaseConnection instanceof Connection) { + throw new InvalidConfigurationException('Connection not found.'); + } + + $this->databaseConnection = $databaseConnection; + } + + private function setUpImportFilePath(): void + { + $folder = PIMCORE_PRIVATE_VAR . '/tmp/datahub/dataimporter/sql-loader/'; + $this->filesystem->mkdir($folder, 0775); + + $this->importFilePath = $folder . uniqid('sql-import-'); + } +} diff --git a/src/PimcoreDataImporterBundle.php b/src/PimcoreDataImporterBundle.php index 76db64d1..0998dff5 100644 --- a/src/PimcoreDataImporterBundle.php +++ b/src/PimcoreDataImporterBundle.php @@ -70,10 +70,12 @@ public function getJsPaths(): array '/bundles/pimcoredataimporter/js/pimcore/configuration/components/loader/asset.js', '/bundles/pimcoredataimporter/js/pimcore/configuration/components/loader/upload.js', '/bundles/pimcoredataimporter/js/pimcore/configuration/components/loader/push.js', + '/bundles/pimcoredataimporter/js/pimcore/configuration/components/loader/sql.js', '/bundles/pimcoredataimporter/js/pimcore/configuration/components/interpreter/csv.js', '/bundles/pimcoredataimporter/js/pimcore/configuration/components/interpreter/json.js', '/bundles/pimcoredataimporter/js/pimcore/configuration/components/interpreter/xlsx.js', '/bundles/pimcoredataimporter/js/pimcore/configuration/components/interpreter/xml.js', + '/bundles/pimcoredataimporter/js/pimcore/configuration/components/interpreter/sql.js', '/bundles/pimcoredataimporter/js/pimcore/configuration/components/cleanup/unpublish.js', '/bundles/pimcoredataimporter/js/pimcore/configuration/components/cleanup/delete.js', '/bundles/pimcoredataimporter/js/pimcore/configuration/components/importSettings.js', diff --git a/src/Resources/config/pimcore/routing.yml b/src/Resources/config/pimcore/routing.yml index f976c452..e73fef32 100644 --- a/src/Resources/config/pimcore/routing.yml +++ b/src/Resources/config/pimcore/routing.yml @@ -4,6 +4,12 @@ _data_hub_data_importer_data_object_admin: options: expose: true +_data_hub_data_importer_connections: + resource: "@PimcoreDataImporterBundle/Controller/ConnectionController.php" + type: annotation + options: + expose: true + _data_hub_data_importer_data_object_push: resource: "@PimcoreDataImporterBundle/Controller/PushImportController.php" type: annotation diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index 10e664a4..8c887b5e 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -59,6 +59,10 @@ services: tags: - { name: "pimcore.datahub.data_importer.loader", type: "push" } + Pimcore\Bundle\DataImporterBundle\DataSource\Loader\SqlLoader: + tags: + - { name: "pimcore.datahub.data_importer.loader", type: "sql" } + Pimcore\Bundle\DataImporterBundle\DataSource\Interpreter\DeltaChecker\DeltaChecker: ~ Pimcore\Bundle\DataImporterBundle\DataSource\Interpreter\InterpreterFactory: ~ @@ -91,6 +95,13 @@ services: - { name: monolog.logger, channel: 'DATA-IMPORTER' } - { name: "pimcore.datahub.data_importer.interpreter", type: "xml" } + Pimcore\Bundle\DataImporterBundle\DataSource\Interpreter\SqlFileInterpreter: + calls: + - [ setLogger, [ '@logger' ] ] + tags: + - { name: monolog.logger, channel: 'DATA-IMPORTER' } + - { name: "pimcore.datahub.data_importer.interpreter", type: "sql" } + Pimcore\Bundle\DataImporterBundle\Cleanup\CleanupStrategyFactory: ~ Pimcore\Bundle\DataImporterBundle\Cleanup\DeleteStrategy: diff --git a/src/Resources/public/js/pimcore/configuration/components/interpreter/sql.js b/src/Resources/public/js/pimcore/configuration/components/interpreter/sql.js new file mode 100644 index 00000000..49e623a5 --- /dev/null +++ b/src/Resources/public/js/pimcore/configuration/components/interpreter/sql.js @@ -0,0 +1,36 @@ +/** + * Pimcore + * + * This source file is available under two different licenses: + * - GNU General Public License version 3 (GPLv3) + * - Pimcore Commercial License (PCL) + * Full copyright and license information is available in + * LICENSE.md which is distributed with this source code. + * + * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org) + * @license http://www.pimcore.org/license GPLv3 and PCL + */ + +pimcore.registerNS("pimcore.plugin.pimcoreDataImporterBundle.configuration.components.interpreter.sql"); +pimcore.plugin.pimcoreDataImporterBundle.configuration.components.interpreter.sql = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.abstractOptionType, { + + type: 'sql', + + buildSettingsForm: function() { + + if(!this.form) { + this.form = Ext.create('DataHub.DataImporter.StructuredValueForm', { + defaults: { + labelWidth: 200, + width: 600 + }, + border: false, + items: [ + ] + }); + } + + return this.form; + } + +}); \ No newline at end of file diff --git a/src/Resources/public/js/pimcore/configuration/components/loader/sql.js b/src/Resources/public/js/pimcore/configuration/components/loader/sql.js new file mode 100644 index 00000000..63ae901a --- /dev/null +++ b/src/Resources/public/js/pimcore/configuration/components/loader/sql.js @@ -0,0 +1,104 @@ +/** + * Pimcore + * + * This source file is available under two different licenses: + * - GNU General Public License version 3 (GPLv3) + * - Pimcore Commercial License (PCL) + * Full copyright and license information is available in + * LICENSE.md which is distributed with this source code. + * + * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org) + * @license http://www.pimcore.org/license GPLv3 and PCL + */ + +pimcore.registerNS("pimcore.plugin.pimcoreDataImporterBundle.configuration.components.loader.sql"); +pimcore.plugin.pimcoreDataImporterBundle.configuration.components.loader.sql = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.abstractOptionType, { + + type: 'sql', + + buildSettingsForm: function() { + + if(!this.form) { + const dataStore = Ext.create('Ext.data.Store', { + autoLoad: true, + proxy: { + type: 'ajax', + url: Routing.generate('pimcore_dataimporter_connections'), + reader: { + type: 'json' + } + } + }); + + this.form = Ext.create('DataHub.DataImporter.StructuredValueForm', { + defaults: { + labelWidth: 200, + width: 600 + }, + border: false, + items: [ + { + xtype: 'combobox', + fieldLabel: t('plugin_pimcore_datahub_data_importer_configpanel_sql_connection'), + name: this.dataNamePrefix + 'connection', + value: this.data.connection, + allowBlank: false, + msgTarget: 'under', + displayField: 'name', + valueField: 'value', + store: dataStore, + }, + { + xtype: 'textarea', + fieldLabel: "SELECT
(eg. a,b,c)*", + name: this.dataNamePrefix + 'select', + value: this.data.select, + msgTarget: 'under', + width: 900, + height: 200, + grow: true, + growMax: 400, + allowBlank: false, + }, + { + xtype: 'textarea', + fieldLabel: "FROM
(eg. d INNER JOIN e ON c.a = e.b)*", + name: this.dataNamePrefix + 'from', + value: this.data.from, + msgTarget: 'under', + width: 900, + height: 200, + grow: true, + growMax: 400, + allowBlank: false, + }, + { + xtype: 'textarea', + fieldLabel: "WHERE
(eg. c = 'some_value')", + name: this.dataNamePrefix + 'where', + value: this.data.where, + msgTarget: 'under', + width: 900, + height: 200, + grow: true, + growMax: 400, + }, + { + xtype: 'textarea', + fieldLabel: "GROUP BY
(eg. b, c )", + name: this.dataNamePrefix + 'groupBy', + value: this.data.groupBy, + msgTarget: 'under', + width: 900, + height: 200, + grow: true, + growMax: 400, + }, + ] + }); + } + + return this.form; + } + +}); \ No newline at end of file diff --git a/src/Resources/translations/admin.en.yml b/src/Resources/translations/admin.en.yml index 700bf11f..83ea71db 100644 --- a/src/Resources/translations/admin.en.yml +++ b/src/Resources/translations/admin.en.yml @@ -206,3 +206,5 @@ plugin_pimcore_datahub_data_importer_configpanel_execution_date_format: Date &am plugin_pimcore_datahub_data_importer_configpanel_logs: Import Logs plugin_pimcore_datahub_data_importer_configpanel_mtm_relation_type_error: Type not supported for Many To Many Relation assignment. plugin_pimcore_datahub_data_importer_configpanel_mtm_relation_type: Make sure transformation results in a 'dataObjectArray' or an 'assetArray'. +plugin_pimcore_datahub_data_importer_configpanel_type_sql: SQL +plugin_pimcore_datahub_data_importer_configpanel_sql_connection: Connection \ No newline at end of file