Merge branch 'release/v4-0-0'
This commit is contained in:
commit
562c0a0c28
|
@ -89,7 +89,7 @@ from MySQL to PostgreSQL as easy and smooth as possible.</p>
|
|||
<b>Note:</b> "logs_directory" will be created during script execution.</p>
|
||||
|
||||
<h3>VERSION</h3>
|
||||
<p>Current version is 3.5.0<br />
|
||||
<p>Current version is 4.0.0<br />
|
||||
(major version . improvements . bug fixes)</p>
|
||||
|
||||
<h3>KNOWN ISSUES</h3>
|
||||
|
|
|
@ -81,16 +81,23 @@
|
|||
],
|
||||
"exclude_tables": [],
|
||||
|
||||
"migrate_only_data_description" : [
|
||||
"In order to skip schema migration, and just migrate data into a preset schema",
|
||||
" - set this parameter true."
|
||||
"include_tables_description": [
|
||||
"List (Array) of tables, that will not be migrated.",
|
||||
"By default, nmig will migrate all tables."
|
||||
],
|
||||
"migrate_only_data" : false,
|
||||
"include_tables": [],
|
||||
|
||||
"migrate_only_data_description" : [
|
||||
"In order to skip schema migration, and just migrate data into a preset tables",
|
||||
"fill following array with preset table names.",
|
||||
"If all of your tables are preset, then use '*'"
|
||||
],
|
||||
"migrate_only_data" : [],
|
||||
|
||||
"delimiter_description" : [
|
||||
"Specifies the character, that separates columns within each record.",
|
||||
"This must be a single one-byte character.",
|
||||
"The default is comma."
|
||||
"Specifies the character, that separates columns within each record.",
|
||||
"This must be a single one-byte character.",
|
||||
"The default is comma."
|
||||
],
|
||||
"delimiter" : ",",
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
"tables" : [
|
||||
{
|
||||
"name" : {
|
||||
"original" : "admins",
|
||||
"new" : "renamed_admins"
|
||||
"original" : "salary",
|
||||
"new" : "renamed_salary"
|
||||
},
|
||||
|
||||
"columns" : [
|
||||
|
@ -35,21 +35,16 @@
|
|||
},
|
||||
|
||||
{
|
||||
"original" : "username",
|
||||
"new" : "renamed_username"
|
||||
},
|
||||
|
||||
{
|
||||
"original" : "group_id",
|
||||
"new" : "renamed_group_id"
|
||||
"original" : "employee_id",
|
||||
"new" : "renamed_employee_id"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name" : {
|
||||
"original" : "groups",
|
||||
"new" : "renamed_groups"
|
||||
"original" : "contract",
|
||||
"new" : "renamed_contract"
|
||||
},
|
||||
|
||||
"columns" : [
|
||||
|
|
197
package-lock.json
generated
197
package-lock.json
generated
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "nmig",
|
||||
"version": "3.5.0",
|
||||
"version": "4.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -14,15 +14,15 @@
|
|||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "10.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.0.tgz",
|
||||
"integrity": "sha512-3TUHC3jsBAB7qVRGxT6lWyYo2v96BMmD2PTcl47H25Lu7UXtFH/2qqmKiVrnel6Ne//0TFYf6uvNX+HW2FRkLQ==",
|
||||
"version": "11.13.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.4.tgz",
|
||||
"integrity": "sha512-+rabAZZ3Yn7tF/XPGHupKIL5EcAbrLxnTr/hgQICxbeuAfWtT0UZSfULE+ndusckBItcv4o6ZeOJplQikVcLvQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/pg": {
|
||||
"version": "7.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-7.4.11.tgz",
|
||||
"integrity": "sha512-Eksj2yOBNHnNqLuU1AqwF1qXgdaYDcWVH1ZQlxS7k1i34+JZd/ZNd15ugIpTVQxmBBMqjliJstmrnusjXy08Tg==",
|
||||
"version": "7.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-7.4.14.tgz",
|
||||
"integrity": "sha512-2e4XapP9V/X42IGByC5IHzCzHqLLCNJid8iZBbkk6lkaDMvli8Rk62YE9wjGcLD5Qr5Zaw1ShkQyXy91PI8C0Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
|
@ -39,9 +39,9 @@
|
|||
}
|
||||
},
|
||||
"@types/tape": {
|
||||
"version": "4.2.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.32.tgz",
|
||||
"integrity": "sha512-xil0KO5wkPoixdBWGIGolPv9dekf6dVkjjJLAFYchfKcd4DICou67rgGCIO7wAh3i5Ff/6j9IDgZz+GU9cMaqQ==",
|
||||
"version": "4.2.33",
|
||||
"resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz",
|
||||
"integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
|
@ -69,9 +69,9 @@
|
|||
}
|
||||
},
|
||||
"buffer-writer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-1.0.1.tgz",
|
||||
"integrity": "sha1-Iqk2kB4wKa/NdUfrRIfOtpejvwg="
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
|
||||
"integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw=="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
|
@ -91,13 +91,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
|
||||
"integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
||||
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"foreach": "^2.0.5",
|
||||
"object-keys": "^1.0.8"
|
||||
"object-keys": "^1.0.12"
|
||||
}
|
||||
},
|
||||
"defined": {
|
||||
|
@ -107,27 +106,28 @@
|
|||
"dev": true
|
||||
},
|
||||
"es-abstract": {
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
|
||||
"integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
|
||||
"integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es-to-primitive": "^1.1.1",
|
||||
"es-to-primitive": "^1.2.0",
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.1",
|
||||
"is-callable": "^1.1.3",
|
||||
"is-regex": "^1.0.4"
|
||||
"has": "^1.0.3",
|
||||
"is-callable": "^1.1.4",
|
||||
"is-regex": "^1.0.4",
|
||||
"object-keys": "^1.0.12"
|
||||
}
|
||||
},
|
||||
"es-to-primitive": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
|
||||
"integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
|
||||
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-callable": "^1.1.1",
|
||||
"is-callable": "^1.1.4",
|
||||
"is-date-object": "^1.0.1",
|
||||
"is-symbol": "^1.0.1"
|
||||
"is-symbol": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"for-each": {
|
||||
|
@ -139,12 +139,6 @@
|
|||
"is-callable": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"foreach": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
|
||||
"integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
|
||||
"dev": true
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
|
@ -158,9 +152,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
||||
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
|
@ -180,6 +174,12 @@
|
|||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
|
||||
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
|
||||
"dev": true
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
|
@ -217,10 +217,13 @@
|
|||
}
|
||||
},
|
||||
"is-symbol": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
|
||||
"integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
|
||||
"dev": true
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
|
||||
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-symbols": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
|
@ -243,9 +246,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.22.2",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz",
|
||||
"integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=",
|
||||
"version": "2.24.0",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
|
||||
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==",
|
||||
"dev": true
|
||||
},
|
||||
"mysql": {
|
||||
|
@ -266,9 +269,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"object-keys": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
|
||||
"integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
||||
"dev": true
|
||||
},
|
||||
"once": {
|
||||
|
@ -281,9 +284,9 @@
|
|||
}
|
||||
},
|
||||
"packet-reader": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-0.3.1.tgz",
|
||||
"integrity": "sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc="
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
|
||||
"integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
|
@ -292,21 +295,21 @@
|
|||
"dev": true
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
|
||||
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
|
||||
"dev": true
|
||||
},
|
||||
"pg": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-7.5.0.tgz",
|
||||
"integrity": "sha512-VFyAnp8xsMZp8nwZnMp7lmU5QcWDOZSI3IDNcWv6pblsiOXis5o7lD7/zzVK1Z1JTBiIDDGQAMbFMkiUzCL59A==",
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-7.9.0.tgz",
|
||||
"integrity": "sha512-GkzteBFpsIoIBCSuomqik3IGvhqAtTr32jclR24RmUg170Jrn6ypwR97YalFHrsE1iaW8T0aAH13dmij8QUQ0g==",
|
||||
"requires": {
|
||||
"buffer-writer": "1.0.1",
|
||||
"packet-reader": "0.3.1",
|
||||
"buffer-writer": "2.0.0",
|
||||
"packet-reader": "1.0.0",
|
||||
"pg-connection-string": "0.1.3",
|
||||
"pg-pool": "~2.0.3",
|
||||
"pg-types": "~1.12.1",
|
||||
"pg-pool": "^2.0.4",
|
||||
"pg-types": "~2.0.0",
|
||||
"pgpass": "1.x",
|
||||
"semver": "4.3.2"
|
||||
}
|
||||
|
@ -317,23 +320,29 @@
|
|||
"integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc="
|
||||
},
|
||||
"pg-copy-streams": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-copy-streams/-/pg-copy-streams-1.2.0.tgz",
|
||||
"integrity": "sha1-ez+d7gtsX8IGj1nED6IY4MHXQkk="
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-copy-streams/-/pg-copy-streams-2.2.0.tgz",
|
||||
"integrity": "sha512-w1gy/KAD49vaCCUfqcjh4fy1V4TF6fvtZ+EaRAU0QKtADMxihb+qYRgbWTDbi6Lh6v31CsWC0ru8vCDHofrRQQ=="
|
||||
},
|
||||
"pg-int8": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
||||
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
|
||||
},
|
||||
"pg-pool": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.3.tgz",
|
||||
"integrity": "sha1-wCIDLIlJ8xKk+R+2QJzgQHa+Mlc="
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.6.tgz",
|
||||
"integrity": "sha512-hod2zYQxM8Gt482q+qONGTYcg/qVcV32VHVPtktbBJs0us3Dj7xibISw0BAAXVMCzt8A/jhfJvpZaxUlqtqs0g=="
|
||||
},
|
||||
"pg-types": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.12.1.tgz",
|
||||
"integrity": "sha1-1kCH45A7WP+q0nnnWVxSIIoUw9I=",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.0.1.tgz",
|
||||
"integrity": "sha512-b7y6QM1VF5nOeX9ukMQ0h8a9z89mojrBHXfJeSug4mhL0YpxNBm83ot2TROyoAmX/ZOX3UbwVO4EbH7i1ZZNiw==",
|
||||
"requires": {
|
||||
"postgres-array": "~1.0.0",
|
||||
"pg-int8": "1.0.1",
|
||||
"postgres-array": "~2.0.0",
|
||||
"postgres-bytea": "~1.0.0",
|
||||
"postgres-date": "~1.0.0",
|
||||
"postgres-date": "~1.0.4",
|
||||
"postgres-interval": "^1.1.0"
|
||||
}
|
||||
},
|
||||
|
@ -346,9 +355,9 @@
|
|||
}
|
||||
},
|
||||
"postgres-array": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.3.tgz",
|
||||
"integrity": "sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ=="
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
|
||||
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="
|
||||
},
|
||||
"postgres-bytea": {
|
||||
"version": "1.0.0",
|
||||
|
@ -356,14 +365,14 @@
|
|||
"integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU="
|
||||
},
|
||||
"postgres-date": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.3.tgz",
|
||||
"integrity": "sha1-4tiXAu/bJY/52c7g/pG9BpdSV6g="
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.4.tgz",
|
||||
"integrity": "sha512-bESRvKVuTrjoBluEcpv2346+6kgB7UlnqWZsnbnCccTNq/pqfj1j6oBaN5+b/NrDXepYUT/HKadqv3iS9lJuVA=="
|
||||
},
|
||||
"postgres-interval": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.1.2.tgz",
|
||||
"integrity": "sha512-fC3xNHeTskCxL1dC8KOtxXt7YeFmlbTYtn7ul8MkVERuTmf7pI4DrkAxcw3kh1fQ9uz4wQmd03a1mRiXUZChfQ==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
|
||||
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
|
||||
"requires": {
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
|
@ -388,12 +397,12 @@
|
|||
}
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
|
||||
"integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
|
||||
"integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-parse": "^1.0.5"
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"resumer": {
|
||||
|
@ -448,21 +457,21 @@
|
|||
}
|
||||
},
|
||||
"tape": {
|
||||
"version": "4.9.1",
|
||||
"resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz",
|
||||
"integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==",
|
||||
"version": "4.10.1",
|
||||
"resolved": "https://registry.npmjs.org/tape/-/tape-4.10.1.tgz",
|
||||
"integrity": "sha512-G0DywYV1jQeY3axeYnXUOt6ktnxS9OPJh97FGR3nrua8lhWi1zPflLxcAHavZ7Jf3qUfY7cxcVIVFa4mY2IY1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"deep-equal": "~1.0.1",
|
||||
"defined": "~1.0.0",
|
||||
"for-each": "~0.3.3",
|
||||
"function-bind": "~1.1.1",
|
||||
"glob": "~7.1.2",
|
||||
"glob": "~7.1.3",
|
||||
"has": "~1.0.3",
|
||||
"inherits": "~2.0.3",
|
||||
"minimist": "~1.2.0",
|
||||
"object-inspect": "~1.6.0",
|
||||
"resolve": "~1.7.1",
|
||||
"resolve": "~1.10.0",
|
||||
"resumer": "~0.0.0",
|
||||
"string.prototype.trim": "~1.1.2",
|
||||
"through": "~2.3.8"
|
||||
|
@ -474,9 +483,9 @@
|
|||
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.3.tgz",
|
||||
"integrity": "sha512-+81MUSyX+BaSo+u2RbozuQk/UWx6hfG0a5gHu4ANEM4sU96XbuIyAB+rWBW1u70c6a5QuZfuYICn3s2UjuHUpA==",
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz",
|
||||
"integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==",
|
||||
"dev": true
|
||||
},
|
||||
"util-deprecate": {
|
||||
|
|
16
package.json
16
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "nmig",
|
||||
"version": "3.5.0",
|
||||
"version": "4.0.0",
|
||||
"description": "The database migration app",
|
||||
"author": "Anatoly Khaytovich<anatolyuss@gmail.com>",
|
||||
"license": "GPL-3.0",
|
||||
|
@ -13,16 +13,16 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"mysql": "^2.16.0",
|
||||
"pg": "^7.5.0",
|
||||
"pg-copy-streams": "^1.2.0"
|
||||
"pg": "^7.9.0",
|
||||
"pg-copy-streams": "^2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mysql": "^2.15.5",
|
||||
"@types/node": "^10.12.0",
|
||||
"@types/pg": "^7.4.11",
|
||||
"@types/tape": "^4.2.32",
|
||||
"tape": "^4.9.1",
|
||||
"typescript": "^3.1.3"
|
||||
"@types/node": "^11.13.4",
|
||||
"@types/pg": "^7.4.14",
|
||||
"@types/tape": "^4.2.33",
|
||||
"tape": "^4.10.1",
|
||||
"typescript": "^3.4.3"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
|
|
|
@ -34,28 +34,18 @@ import { dropDataChunkIdColumn } from './ConsistencyEnforcer';
|
|||
import Conversion from './Conversion';
|
||||
|
||||
/**
|
||||
* Continues migration process after data loading, when migrate_only_data is true.
|
||||
* Continues migration process after data loading.
|
||||
*/
|
||||
async function continueProcessAfterDataLoadingShort(conversion: Conversion): Promise<void> {
|
||||
const promises: Promise<void>[] = conversion._tablesToMigrate.map(async (tableName: string) => {
|
||||
await dropDataChunkIdColumn(conversion, tableName);
|
||||
return sequencesProcessor.setSequenceValue(conversion, tableName);
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
await dataPoolManager.dropDataPoolTable(conversion);
|
||||
await runVacuumFullAndAnalyze(conversion);
|
||||
await migrationStateManager.dropStateLogsTable(conversion);
|
||||
generateReport(conversion, 'NMIG migration is accomplished.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues migration process after data loading, when migrate_only_data is false.
|
||||
*/
|
||||
async function continueProcessAfterDataLoadingLong(conversion: Conversion): Promise<void> {
|
||||
export default async function(conversion: Conversion): Promise<void> {
|
||||
const isTableConstraintsLoaded: boolean = await migrationStateManager.get(conversion, 'per_table_constraints_loaded');
|
||||
|
||||
const promises: Promise<void>[] = conversion._tablesToMigrate.map(async (tableName: string) => {
|
||||
if (!isTableConstraintsLoaded) {
|
||||
if (conversion.shouldMigrateOnlyDataFor(tableName)) {
|
||||
await dropDataChunkIdColumn(conversion, tableName);
|
||||
return sequencesProcessor.setSequenceValue(conversion, tableName);
|
||||
}
|
||||
|
||||
await dropDataChunkIdColumn(conversion, tableName);
|
||||
await processEnum(conversion, tableName);
|
||||
await processNull(conversion, tableName);
|
||||
|
@ -77,15 +67,3 @@ async function continueProcessAfterDataLoadingLong(conversion: Conversion): Prom
|
|||
await migrationStateManager.dropStateLogsTable(conversion);
|
||||
generateReport(conversion, 'NMIG migration is accomplished.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues migration process after data loading.
|
||||
*/
|
||||
export default async function(conversion: Conversion): Promise<void> {
|
||||
if (conversion._migrateOnlyData) {
|
||||
await continueProcessAfterDataLoadingShort(conversion);
|
||||
return;
|
||||
}
|
||||
|
||||
await continueProcessAfterDataLoadingLong(conversion);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import * as path from 'path';
|
|||
import { EventEmitter } from 'events';
|
||||
import { Pool as MySQLPool } from 'mysql';
|
||||
import { Pool as PgPool } from 'pg';
|
||||
import { Encoding } from './Encoding';
|
||||
|
||||
export default class Conversion {
|
||||
/**
|
||||
|
@ -57,7 +58,7 @@ export default class Conversion {
|
|||
/**
|
||||
* JavaScript encoding type.
|
||||
*/
|
||||
public readonly _encoding: string;
|
||||
public readonly _encoding: Encoding;
|
||||
|
||||
/**
|
||||
* The path to the "all.log" file.
|
||||
|
@ -75,9 +76,10 @@ export default class Conversion {
|
|||
public readonly _delimiter: string;
|
||||
|
||||
/**
|
||||
* Defines if only the data should be migrated (into a preset schema).
|
||||
* Defines preset tables.
|
||||
* The only thing to do with these tables is a data migration, since the schema is preset.
|
||||
*/
|
||||
public readonly _migrateOnlyData: boolean;
|
||||
public readonly _migrateOnlyData: string[];
|
||||
|
||||
/**
|
||||
* A path to the "logs_directory".
|
||||
|
@ -105,10 +107,15 @@ export default class Conversion {
|
|||
public readonly _noVacuum: string[];
|
||||
|
||||
/**
|
||||
* List of tables, that will not be migrated.List (Array) of tables, that will not be migrated.
|
||||
* List of tables, that will not be migrated.
|
||||
*/
|
||||
public readonly _excludeTables: string[];
|
||||
|
||||
/**
|
||||
* List of tables, that will be migrated.
|
||||
*/
|
||||
public readonly _includeTables: string[];
|
||||
|
||||
/**
|
||||
* The timestamp, at which the migration began.
|
||||
*/
|
||||
|
@ -208,9 +215,10 @@ export default class Conversion {
|
|||
this._notCreatedViewsPath = path.join(this._logsDirPath, 'not_created_views');
|
||||
this._noVacuum = this._config.no_vacuum === undefined ? [] : this._config.no_vacuum;
|
||||
this._excludeTables = this._config.exclude_tables === undefined ? [] : this._config.exclude_tables;
|
||||
this._includeTables = this._config.include_tables === undefined ? [] : this._config.include_tables;
|
||||
this._timeBegin = new Date();
|
||||
this._encoding = this._config.encoding === undefined ? 'utf8' : this._config.encoding;
|
||||
this._dataChunkSize = this._config.data_chunk_size === undefined ? 1 : +this._config.data_chunk_size;
|
||||
this._dataChunkSize = this._config.data_chunk_size === undefined ? 1 : Math.ceil(+this._config.data_chunk_size);
|
||||
this._dataChunkSize = this._dataChunkSize <= 0 ? 1 : this._dataChunkSize;
|
||||
this._0777 = '0777';
|
||||
this._mysqlVersion = '5.6.21'; // Simply a default value.
|
||||
|
@ -236,12 +244,19 @@ export default class Conversion {
|
|||
this._maxDbConnectionPoolSize = this._maxDbConnectionPoolSize > 0 ? this._maxDbConnectionPoolSize : 10;
|
||||
this._loaderMaxOldSpaceSize = this._config.loader_max_old_space_size;
|
||||
this._loaderMaxOldSpaceSize = Conversion._isIntNumeric(this._loaderMaxOldSpaceSize) ? this._loaderMaxOldSpaceSize : 'DEFAULT';
|
||||
this._migrateOnlyData = this._config.migrate_only_data === undefined ? false : this._config.migrate_only_data;
|
||||
this._migrateOnlyData = this._config.migrate_only_data === undefined ? [] : this._config.migrate_only_data;
|
||||
this._delimiter = this._config.delimiter !== undefined && this._config.delimiter.length === 1
|
||||
? this._config.delimiter
|
||||
: ',';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are actions to take on given table other than data migration.
|
||||
*/
|
||||
public shouldMigrateOnlyDataFor(tableName: string): boolean {
|
||||
return this._migrateOnlyData.indexOf(tableName) !== -1 || this._migrateOnlyData.indexOf('*') !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given value is integer number.
|
||||
*/
|
||||
|
|
|
@ -43,7 +43,7 @@ export default async (conversion: Conversion, tableName: string, haveDataChunksP
|
|||
const dbAccess: DBAccess = new DBAccess(conversion);
|
||||
const sizeQueryResult: DBAccessQueryResult = await dbAccess.query(logTitle, sql, DBVendors.MYSQL, true, true);
|
||||
|
||||
const tableSizeInMb: number = +sizeQueryResult.data[0].size_in_mb;
|
||||
const tableSizeInMb: number = Math.ceil(+sizeQueryResult.data[0].size_in_mb);
|
||||
const strSelectFieldList: string = arrangeColumnsData(conversion._dicTables[tableName].arrTableColumns, conversion._mysqlVersion);
|
||||
sql = `SELECT COUNT(1) AS rows_count FROM \`${ originalTableName }\`;`;
|
||||
const countResult: DBAccessQueryResult = await dbAccess.query(
|
||||
|
@ -56,8 +56,7 @@ export default async (conversion: Conversion, tableName: string, haveDataChunksP
|
|||
);
|
||||
|
||||
const rowsCnt: number = countResult.data[0].rows_count;
|
||||
let chunksCnt: number = tableSizeInMb / conversion._dataChunkSize;
|
||||
chunksCnt = chunksCnt < 1 ? 1 : chunksCnt;
|
||||
const chunksCnt: number = Math.ceil(tableSizeInMb / conversion._dataChunkSize);
|
||||
const rowsInChunk: number = Math.ceil(rowsCnt / chunksCnt);
|
||||
const arrDataPoolPromises: Promise<void>[] = [];
|
||||
const msg: string = `\t--[prepareDataChunks] Total rows to insert into "${ conversion._schema }"."${ tableName }": ${ rowsCnt }`;
|
||||
|
@ -78,8 +77,8 @@ export default async (conversion: Conversion, tableName: string, haveDataChunksP
|
|||
if (chunksCnt === 1) {
|
||||
currentChunkSizeInMb = tableSizeInMb;
|
||||
} else if (offset + rowsInChunk >= rowsCnt) {
|
||||
currentChunkSizeInMb = tableSizeInMb % chunksCnt;
|
||||
currentChunkSizeInMb = currentChunkSizeInMb || conversion._dataChunkSize;
|
||||
// !!!Note, it can happen only on the last iteration, when defining a size of the last chunk.
|
||||
currentChunkSizeInMb = tableSizeInMb - conversion._dataChunkSize * (chunksCnt - 1);
|
||||
} else {
|
||||
currentChunkSizeInMb = conversion._dataChunkSize;
|
||||
}
|
||||
|
|
|
@ -100,6 +100,27 @@ function fillBandwidth(conversion: Conversion): number[] {
|
|||
}
|
||||
}
|
||||
|
||||
if (dataChunkIndexes.length === 0 && conversion._dataPool.length !== 0) {
|
||||
// This is the case where there are chunks, larger than "conversion._dataChunkSize".
|
||||
// It may happen with maximum one chunk per table.
|
||||
// See calculations from DataChunksProcessor.ts for the reference.
|
||||
//
|
||||
// Each call to "fillBandwidth()" will return an index of one (and only one!!!) such chunk.
|
||||
// Eventually, all of the chunks, including the "bigger" ones, will be processed.
|
||||
const firstUnprocessedChunkIndex: number = conversion
|
||||
._dataPool
|
||||
.findIndex((item: any) => item._processed === false);
|
||||
|
||||
if (firstUnprocessedChunkIndex === -1) {
|
||||
const msg: string = 'Something went wrong with DataPipeManager.';
|
||||
log(conversion, msg, undefined, true);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
dataChunkIndexes.push(firstUnprocessedChunkIndex);
|
||||
conversion._dataPool[firstUnprocessedChunkIndex]._processed = true;
|
||||
}
|
||||
|
||||
return dataChunkIndexes;
|
||||
}
|
||||
|
||||
|
@ -114,9 +135,8 @@ async function pipeData(conversion: Conversion, dataLoaderPath: string, options:
|
|||
return processConstraints(conversion);
|
||||
}
|
||||
|
||||
const chunksToLoad: any[] = fillBandwidth(conversion).map((index: number) => conversion._dataPool[index]);
|
||||
const loaderProcess: ChildProcess = fork(dataLoaderPath, options);
|
||||
const bandwidth: number[] = fillBandwidth(conversion);
|
||||
const chunksToLoad: any[] = bandwidth.map((index: number) => conversion._dataPool[index]);
|
||||
|
||||
loaderProcess.on('message', async (signal: any) => {
|
||||
if (typeof signal === 'object') {
|
||||
|
|
21
src/Encoding.ts
Normal file
21
src/Encoding.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* This file is a part of "NMIG" - the database migration tool.
|
||||
*
|
||||
* Copyright (C) 2016 - present, Anatoly Khaytovich <anatolyuss@gmail.com>
|
||||
*
|
||||
* This program is free software= you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful;
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (please see the "LICENSE.md" file).
|
||||
* If not; see <http=//www.gnu.org/licenses/gpl.txt>.
|
||||
*
|
||||
* @author Anatoly Khaytovich <anatolyuss@gmail.com>
|
||||
*/
|
||||
export type Encoding = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'latin1' | 'binary' | 'hex';
|
|
@ -62,7 +62,17 @@ export default async (conversion: Conversion): Promise<Conversion> => {
|
|||
await getMySqlVersion(conversion);
|
||||
const dbAccess: DBAccess = new DBAccess(conversion);
|
||||
const haveTablesLoaded: boolean = await migrationStateManager.get(conversion, 'tables_loaded');
|
||||
const sql: string = `SHOW FULL TABLES IN \`${ conversion._mySqlDbName }\`;`;
|
||||
let sql: string = `SHOW FULL TABLES IN \`${ conversion._mySqlDbName }\` WHERE 1 = 1`;
|
||||
|
||||
if (conversion._includeTables.length !== 0) {
|
||||
sql += ` AND Tables_in_${ conversion._mySqlDbName } IN(${ conversion._includeTables.map((table: string) => `"${table}"`).join(',') })`;
|
||||
}
|
||||
|
||||
if (conversion._excludeTables.length !== 0) {
|
||||
sql += ` AND Tables_in_${ conversion._mySqlDbName } NOT IN(${ conversion._excludeTables.map((table: string) => `"${table}"`).join(',') })`;
|
||||
}
|
||||
|
||||
sql += ';';
|
||||
const result: DBAccessQueryResult = await dbAccess.query('StructureLoader::default', sql, DBVendors.MYSQL, true, false);
|
||||
let tablesCnt: number = 0;
|
||||
let viewsCnt: number = 0;
|
||||
|
|
|
@ -87,7 +87,7 @@ export async function createTable(conversion: Conversion, tableName: string): Pr
|
|||
|
||||
conversion._dicTables[tableName].arrTableColumns = columns.data;
|
||||
|
||||
if (conversion._migrateOnlyData) {
|
||||
if (conversion.shouldMigrateOnlyDataFor(tableName)) {
|
||||
// Although the schema is preset, the data chunk id column must be added.
|
||||
// This is due to the need to enforce data consistency in case of failures.
|
||||
const sqlAddDataChunkIdColumn: string = `ALTER TABLE "${ conversion._schema }"."${ tableName }"
|
||||
|
|
Loading…
Reference in a new issue