Skip to content

feat: mysql2json import/export tool #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .github/workflows/php-package.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
name: PHP Package
env:
PHAR_TOOL_VERSION: 1.4.0
PHAR_TOOL_REPOSITORY: clue/phar-composer
on:
push:
pull_request:
Expand Down Expand Up @@ -26,19 +29,24 @@ jobs:
php-version:
- 8.2
- 8.3
io-driver:
- eio
- uv
- 8.4
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: ${{ matrix.io-driver }}
tools: composer:v2
coverage: xdebug3
- run: composer install
shell: bash
- run: composer test
shell: bash
- name: Download build package
run: gh release download v${{ env.PHAR_TOOL_VERSION }} -R=${{ env.PHAR_TOOL_REPOSITORY }}
env:
GH_TOKEN: ${{ github.token }}
- name: Build package
run: |
chmod +x ./phar-composer-${{ env.PHAR_TOOL_VERSION }}.phar
./phar-composer-${{ env.PHAR_TOOL_VERSION }}.phar build ./ mysql2json
34 changes: 33 additions & 1 deletion .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ on:
push:
branches:
- main
env:
PHAR_TOOL_VERSION: 1.4.0
PHAR_TOOL_REPOSITORY: clue/phar-composer

permissions:
contents: write
Expand All @@ -15,7 +18,36 @@ jobs:
release-please:
needs: verify-release
runs-on: ubuntu-24.04
outputs:
releases_created: ${{ steps.release.outputs.release_created }}
tag: ${{ steps.release.outputs.tag_name }}
steps:
- uses: googleapis/release-please-action@v4
id: release
with:
release-type: php
release-type: php
upload_phar:
needs: release-please
runs-on: ubuntu-24.04
if: ${{ needs.release-please.outputs.releases_created == true }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.release-please.outputs.tag }}
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.2
tools: composer:v2
- name: Download build package
run: gh release download v${{ env.PHAR_TOOL_VERSION }} -R=${{ env.PHAR_TOOL_REPOSITORY }}
- name: Build package
run: |
chmod +x ./phar-composer-${{ env.PHAR_TOOL_VERSION }}.phar
./phar-composer-${{ env.PHAR_TOOL_VERSION }}.phar build ./ mysql2json
env:
GH_TOKEN: ${{ github.token }}
- name: Upload package
run: gh release upload ${{ needs.release-please.outputs.tag }} mysql2json
env:
GH_TOKEN: ${{ github.token }}
18 changes: 17 additions & 1 deletion bin/mysql2jsonl
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
#!env php
#!/usr/bin/env php
<?php

use EcomDev\MySQL2JSONL\Command\ExportCommand;
use EcomDev\MySQL2JSONL\Command\ImportCommand;
use Symfony\Component\Console\Application;

require_once __DIR__ . '/../vendor/autoload.php';

$application = new Application(
basename(__FILE__),
'1.0.0'
);

$application->addCommands([
new ExportCommand(),
new ImportCommand(),
]);

$application->run();
17 changes: 11 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
"type": "library",
"require": {
"php": "~8.2",
"amphp/file": "~3.2",
"amphp/mysql": "~3.0",
"amphp/amp": "~3.0",
"amphp/parallel": "~v2.3.1",
"revolt/event-loop": "~1.0",
"symfony/console": "~7.2"
"symfony/console": "~7.2",
"justinrainbow/json-schema": "^6.0",
"ext-pdo": "*"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.0",
"phpunit/phpunit": "^11.5",
"brianium/paratest": "^7.7",
"ecomdev/testcontainers-magento-data":"~1.1"
"ecomdev/testcontainers-magento-data":"~1.2"
},
"license": [
"MIT"
Expand All @@ -24,16 +25,20 @@
],
"autoload": {
"psr-4": {
"EcomDev\\MySQL2JSONL\\": "src"
"EcomDev\\MySQL2JSONL\\": "src/"
}
},
"autoload-dev": {
"files": [
"tests/fixtures.php"
],
"psr-4": {
"EcomDev\\MySQL2JSONL\\": "tests"
"EcomDev\\MySQL2JSONL\\": "tests/"
}
},
"scripts": {
"test": "XDEBUG_MODE=coverage paratest --coverage-text",
"test:single-threaded": "XDEBUG_MODE=coverage phpunit --coverage-text",
"format:check": "phpcs",
"format:write": "phpcbf"
},
Expand Down
9 changes: 8 additions & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.5/phpunit.xsd" bootstrap="vendor/autoload.php" executionOrder="depends,defects" beStrictAboutOutputDuringTests="true" colors="true" cacheDirectory=".phpunit.cache">
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.5/phpunit.xsd" bootstrap="vendor/autoload.php" executionOrder="depends,defects"
beStrictAboutOutputDuringTests="true"
colors="true"
cacheDirectory=".phpunit.cache"
displayDetailsOnTestsThatTriggerWarnings="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
>
<testsuites>
<testsuite name="default">
<directory>tests</directory>
Expand Down
186 changes: 186 additions & 0 deletions schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
{
"$schema": "https://json-schema.org/draft-04/schema#",
"title": "MySQL2JSONL configuration file",
"type": "object",
"properties": {
"config": {
"$ref": "#/definitions/configuration",
"description": "Configuration settings"
}
},
"required": ["config"],
"definitions": {
"configuration": {
"properties": {
"connection": {
"$ref": "#/definitions/connection",
"description": "MySQL connections settings"
},
"concurrency": {
"type": "integer",
"description": "Maximum concurrency used by tool",
"default": 4
},
"batchSize": {
"type": "integer",
"description": "Batch size for importing data into database",
"default": 1000
},
"includeTables": {
"$ref": "#/definitions/tableConditions",
"description": "List of tables to include from the database dump"
},
"excludeTables": {
"$ref": "#/definitions/tableConditions",
"description": "List of tables to exclude from the database dump"
},
"importMode": {
"$ref": "#/definitions/importMode"
}
},
"required": ["connection"],
"additionalProperties": false
},
"importMode": {
"enum": ["truncate", "update"],
"default": "truncate"
},
"matchExpression": {
"type": "object",
"description": "Match condition for table name",
"properties": {
"regexp": {
"type": "string",
"description": "Valid regular expression for a table name, # sign is prohibited as used as delimiter",
"pattern": "^[^#]+$"
},
"startsWith": {
"type": "string",
"description": "Table name starts with"
},
"endsWith": {
"type": "string",
"description": "Table name ends with"
},
"contains": {
"type": "string",
"description": "Table name contains"
}
},
"minProperties": 1,
"maxProperties": 1
},
"rowCount": {
"type": "object",
"properties": {
"min": {
"type": "integer",
"description": "Minimum number of rows for table to be exported"
},
"max": {
"type": "integer",
"description": "Maximum number of rows for table to be exported"
}
},
"minProperties": 1,
"maxProperties": 1
} ,
"tableName": {
"type": "string",
"pattern": "^[0-9a-zA-Z$_\u0080-\uFFFF]+$"
},
"andCondition": {
"type": "array",
"description": "Table matching conditions",
"items": {
"oneOf": [
{ "$ref": "#/definitions/matchExpression" },
{ "$ref": "#/definitions/rowCount" },
{ "$ref": "#/definitions/tableName" }
]
}
},
"tableConditions": {
"type": "array",
"description": "Table matching conditions",
"default": [],
"items": {
"anyOf": [
{ "$ref": "#/definitions/matchExpression" },
{ "$ref": "#/definitions/rowCount" },
{ "$ref": "#/definitions/tableName" },
{
"type": "object",
"properties": {
"and": {"$ref": "#/definitions/andCondition"}
}
}
]
}
},
"connection": {
"type": "object",
"properties": {
"host": {
"type": "string",
"description": "Host for MySQL host"
},
"unixSocket": {
"type": "string",
"description": "Unix socket path for MySQL connection"
},
"port": {
"type": "integer",
"description": "Port for MySQL connection",
"default": 3306
},
"user": {
"type": "string",
"description": "Username for MySQL connection",
"default": "root"
},
"password": {
"type": "string",
"description": "Password for MySQL connection",
"default": ""
},
"database": {
"type": "string",
"description": "Database for MySQL connection"
},
"charset": {
"type": "string",
"description": "Charset for MySQL connection",
"default": "utf8mb4"
},
"key": {
"type": "string",
"description": "Path to public key to use for sha256_password auth method in MySQL connection"
}
},
"allOf": [
{
"required": [
"database"
]
},
{
"oneOf": [
{
"required": [
"host"
],
"errorMessage": "For connection host or unixSocket must be specified"
},
{
"required": [
"unixSocket"
],
"errorMessage": "For connection host or unixSocket must be specified"
}
]
}
]
}
}
}
Loading