added prettier

This commit is contained in:
Kononnable 2018-02-04 23:38:43 +01:00
parent 76339ddf18
commit 14d064e631
19 changed files with 2634 additions and 1450 deletions

3
.prettierrc Normal file
View File

@ -0,0 +1,3 @@
{
"parser":"typescript"
}

714
package-lock.json generated
View File

@ -214,6 +214,12 @@
"integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
"dev": true
},
"any-observable": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.2.0.tgz",
"integrity": "sha1-xnhwBYADV5AJCD9UrAq6+1wz0kI=",
"dev": true
},
"any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
@ -531,6 +537,12 @@
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
"dev": true
},
"ci-info": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz",
"integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==",
"dev": true
},
"cli-boxes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
@ -602,6 +614,12 @@
}
}
},
"cli-spinners": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz",
"integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=",
"dev": true
},
"cli-truncate": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-1.1.0.tgz",
@ -763,6 +781,30 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"cosmiconfig": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz",
"integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==",
"dev": true,
"requires": {
"is-directory": "0.3.1",
"js-yaml": "3.10.0",
"parse-json": "4.0.0",
"require-from-string": "2.0.1"
},
"dependencies": {
"parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
"dev": true,
"requires": {
"error-ex": "1.3.1",
"json-parse-better-errors": "1.0.1"
}
}
}
},
"create-error-class": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
@ -814,6 +856,12 @@
}
}
},
"date-fns": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz",
"integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw==",
"dev": true
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@ -827,6 +875,12 @@
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
},
"dedent": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
"integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
"dev": true
},
"deep-eql": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
@ -1041,6 +1095,22 @@
"resolved": "https://registry.npmjs.org/figlet/-/figlet-1.2.0.tgz",
"integrity": "sha1-bEZTc3j6tkkUa1phQ92gGbQwtBA="
},
"figures": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
"integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
"dev": true,
"requires": {
"escape-string-regexp": "1.0.5",
"object-assign": "4.1.1"
}
},
"find-parent-dir": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz",
"integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=",
"dev": true
},
"find-up": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
@ -1113,6 +1183,12 @@
"integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
"dev": true
},
"get-own-enumerable-property-symbols": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz",
"integrity": "sha512-TtY/sbOemiMKPRUDDanGCSgBYe7Mf0vbRsWnBZ+9yghpZ1MvcpSpuZFjHdEeY/LZjZy0vdLjS77L6HosisFiug==",
"dev": true
},
"get-stream": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
@ -1325,6 +1401,17 @@
"extend": "3.0.1"
}
},
"husky": {
"version": "0.14.3",
"resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz",
"integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==",
"dev": true,
"requires": {
"is-ci": "1.1.0",
"normalize-path": "1.0.0",
"strip-indent": "2.0.0"
}
},
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
@ -1342,6 +1429,15 @@
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
"dev": true
},
"indent-string": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
"integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
"dev": true,
"requires": {
"repeating": "2.0.1"
}
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -1404,11 +1500,50 @@
"builtin-modules": "1.1.1"
}
},
"is-ci": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz",
"integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==",
"dev": true,
"requires": {
"ci-info": "1.1.2"
}
},
"is-directory": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
"integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
"dev": true
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true
},
"is-finite": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
"integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
"dev": true,
"requires": {
"number-is-nan": "1.0.1"
}
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
},
"is-glob": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
"integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
"dev": true,
"requires": {
"is-extglob": "2.1.1"
}
},
"is-installed-globally": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
@ -1439,6 +1574,15 @@
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
"dev": true
},
"is-observable": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz",
"integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=",
"dev": true,
"requires": {
"symbol-observable": "0.2.4"
}
},
"is-path-inside": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
@ -1454,12 +1598,24 @@
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
"dev": true
},
"is-promise": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
"dev": true
},
"is-redirect": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
"integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
"dev": true
},
"is-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
"integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
"dev": true
},
"is-relative": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz",
@ -1595,6 +1751,24 @@
}
}
},
"jest-get-type": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz",
"integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==",
"dev": true
},
"jest-validate": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.2.1.tgz",
"integrity": "sha512-k4HLI1rZQjlU+EC682RlQ6oZvLrE5SCh3brseQc24vbZTxzT/k/3urar5QMCVgjadmSO7lECeGdc6YxnM3yEGg==",
"dev": true,
"requires": {
"chalk": "2.3.0",
"jest-get-type": "21.2.0",
"leven": "2.1.0",
"pretty-format": "21.2.1"
}
},
"js-string-escape": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
@ -1622,6 +1796,12 @@
"dev": true,
"optional": true
},
"json-parse-better-errors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz",
"integrity": "sha512-xyQpxeWWMKyJps9CuGJYeng6ssI5bpqS9ltQpdVQ90t4ql6NdnxFKh95JcRt2cun/DjMVNrdjniLPuMA69xmCw==",
"dev": true
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
@ -1732,6 +1912,12 @@
"invert-kv": "1.0.0"
}
},
"leven": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
"integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=",
"dev": true
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
@ -1742,12 +1928,353 @@
"type-check": "0.3.2"
}
},
"lint-staged": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-6.1.0.tgz",
"integrity": "sha512-RMB6BUd2bEKaPnj06F7j8RRB8OHM+UP4fQS2LT8lF+X9BjSaezw1oVB5hc4elLhYvzlFCkhAaatzYz+x53YHgw==",
"dev": true,
"requires": {
"app-root-path": "2.0.1",
"chalk": "2.3.0",
"commander": "2.11.0",
"cosmiconfig": "4.0.0",
"debug": "3.1.0",
"dedent": "0.7.0",
"execa": "0.8.0",
"find-parent-dir": "0.3.0",
"is-glob": "4.0.0",
"jest-validate": "21.2.1",
"listr": "0.13.0",
"lodash": "4.17.4",
"log-symbols": "2.2.0",
"minimatch": "3.0.4",
"npm-which": "3.0.1",
"p-map": "1.2.0",
"path-is-inside": "1.0.2",
"pify": "3.0.0",
"staged-git-files": "0.0.4",
"stringify-object": "3.2.1"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"execa": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz",
"integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=",
"dev": true,
"requires": {
"cross-spawn": "5.1.0",
"get-stream": "3.0.0",
"is-stream": "1.1.0",
"npm-run-path": "2.0.2",
"p-finally": "1.0.0",
"signal-exit": "3.0.2",
"strip-eof": "1.0.0"
}
},
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
"dev": true
}
}
},
"listify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/listify/-/listify-1.0.0.tgz",
"integrity": "sha1-A8p7otFQ1CZ3c/dOV1WNEFPSvuM=",
"dev": true
},
"listr": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/listr/-/listr-0.13.0.tgz",
"integrity": "sha1-ILsLowuuZg7oTMBQPfS+PVYjiH0=",
"dev": true,
"requires": {
"chalk": "1.1.3",
"cli-truncate": "0.2.1",
"figures": "1.7.0",
"indent-string": "2.1.0",
"is-observable": "0.2.0",
"is-promise": "2.1.0",
"is-stream": "1.1.0",
"listr-silent-renderer": "1.1.1",
"listr-update-renderer": "0.4.0",
"listr-verbose-renderer": "0.4.1",
"log-symbols": "1.0.2",
"log-update": "1.0.2",
"ora": "0.2.3",
"p-map": "1.2.0",
"rxjs": "5.5.6",
"stream-to-observable": "0.2.0",
"strip-ansi": "3.0.1"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
"ansi-styles": "2.2.1",
"escape-string-regexp": "1.0.5",
"has-ansi": "2.0.0",
"strip-ansi": "3.0.1",
"supports-color": "2.0.0"
}
},
"cli-truncate": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
"integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=",
"dev": true,
"requires": {
"slice-ansi": "0.0.4",
"string-width": "1.0.2"
}
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"requires": {
"number-is-nan": "1.0.1"
}
},
"log-symbols": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
"integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
"dev": true,
"requires": {
"chalk": "1.1.3"
}
},
"slice-ansi": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
"integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
"dev": true
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"requires": {
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
"strip-ansi": "3.0.1"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
}
}
},
"listr-silent-renderer": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz",
"integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=",
"dev": true
},
"listr-update-renderer": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz",
"integrity": "sha1-NE2YDaLKLosUW6MFkI8yrj9MyKc=",
"dev": true,
"requires": {
"chalk": "1.1.3",
"cli-truncate": "0.2.1",
"elegant-spinner": "1.0.1",
"figures": "1.7.0",
"indent-string": "3.2.0",
"log-symbols": "1.0.2",
"log-update": "1.0.2",
"strip-ansi": "3.0.1"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
"ansi-styles": "2.2.1",
"escape-string-regexp": "1.0.5",
"has-ansi": "2.0.0",
"strip-ansi": "3.0.1",
"supports-color": "2.0.0"
}
},
"cli-truncate": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
"integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=",
"dev": true,
"requires": {
"slice-ansi": "0.0.4",
"string-width": "1.0.2"
}
},
"indent-string": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
"integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
"dev": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"requires": {
"number-is-nan": "1.0.1"
}
},
"log-symbols": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
"integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
"dev": true,
"requires": {
"chalk": "1.1.3"
}
},
"slice-ansi": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
"integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
"dev": true
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"requires": {
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
"strip-ansi": "3.0.1"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
}
}
},
"listr-verbose-renderer": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz",
"integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=",
"dev": true,
"requires": {
"chalk": "1.1.3",
"cli-cursor": "1.0.2",
"date-fns": "1.29.0",
"figures": "1.7.0"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
"ansi-styles": "2.2.1",
"escape-string-regexp": "1.0.5",
"has-ansi": "2.0.0",
"strip-ansi": "3.0.1",
"supports-color": "2.0.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
}
}
},
"load-json-file": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
@ -1774,12 +2301,27 @@
"integrity": "sha1-Jjj8OaAzHpysGgS3F5mTHJxQ33k=",
"dev": true
},
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
"dev": true
},
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
"dev": true
},
"log-symbols": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
"integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
"dev": true,
"requires": {
"chalk": "2.3.0"
}
},
"log-update": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz",
@ -2055,6 +2597,21 @@
"validate-npm-package-license": "3.0.1"
}
},
"normalize-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz",
"integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=",
"dev": true
},
"npm-path": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz",
"integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==",
"dev": true,
"requires": {
"which": "1.3.0"
}
},
"npm-run-path": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
@ -2063,6 +2620,17 @@
"path-key": "2.0.1"
}
},
"npm-which": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz",
"integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=",
"dev": true,
"requires": {
"commander": "2.11.0",
"npm-path": "2.0.4",
"which": "1.3.0"
}
},
"number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
@ -2133,6 +2701,60 @@
}
}
},
"ora": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz",
"integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=",
"dev": true,
"requires": {
"chalk": "1.1.3",
"cli-cursor": "1.0.2",
"cli-spinners": "0.1.2",
"object-assign": "4.1.1"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
"ansi-styles": "2.2.1",
"escape-string-regexp": "1.0.5",
"has-ansi": "2.0.0",
"strip-ansi": "3.0.1",
"supports-color": "2.0.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
}
}
},
"oracledb": {
"version": "2.0.15",
"resolved": "https://registry.npmjs.org/oracledb/-/oracledb-2.0.15.tgz",
@ -2169,6 +2791,12 @@
"p-limit": "1.2.0"
}
},
"p-map": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
"integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
"dev": true
},
"p-try": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
@ -2444,6 +3072,22 @@
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
"dev": true
},
"prettier": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.10.2.tgz",
"integrity": "sha512-TcdNoQIWFoHblurqqU6d1ysopjq7UX0oRcT/hJ8qvBAELiYWn+Ugf0AXdnzISEJ7vuhNnQ98N8jR8Sh53x4IZg==",
"dev": true
},
"pretty-format": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz",
"integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==",
"dev": true,
"requires": {
"ansi-regex": "3.0.0",
"ansi-styles": "3.2.0"
}
},
"process-nextick-args": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
@ -2581,6 +3225,15 @@
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
},
"repeating": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
"integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
"dev": true,
"requires": {
"is-finite": "1.0.2"
}
},
"request": {
"version": "2.81.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
@ -2616,6 +3269,12 @@
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
},
"require-from-string": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.1.tgz",
"integrity": "sha1-xUUjPp19pmFunVmt+zn8n1iGdv8=",
"dev": true
},
"require-main-filename": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
@ -2655,6 +3314,23 @@
"glob": "7.1.2"
}
},
"rxjs": {
"version": "5.5.6",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.6.tgz",
"integrity": "sha512-v4Q5HDC0FHAQ7zcBX7T2IL6O5ltl1a2GX4ENjPXg6SjDY69Cmx9v4113C99a4wGF16ClPv5Z8mghuYorVkg/kg==",
"dev": true,
"requires": {
"symbol-observable": "1.0.1"
},
"dependencies": {
"symbol-observable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
"integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=",
"dev": true
}
}
},
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
@ -2865,6 +3541,21 @@
}
}
},
"staged-git-files": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-0.0.4.tgz",
"integrity": "sha1-15fhtVHKemOd7AI33G60u5vhfTU=",
"dev": true
},
"stream-to-observable": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.2.0.tgz",
"integrity": "sha1-WdbqOT2HwsDdrBCqDVYbxrpvDhA=",
"dev": true,
"requires": {
"any-observable": "0.2.0"
}
},
"string-template": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz",
@ -2888,6 +3579,17 @@
"safe-buffer": "5.1.1"
}
},
"stringify-object": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.2.1.tgz",
"integrity": "sha512-jPcQYw/52HUPP8uOE4kkjxl5bB9LfHkKCTptIk3qw7ozP5XMIMlHMLjt00GGSwW6DJAf/njY5EU6Vpwl4LlBKQ==",
"dev": true,
"requires": {
"get-own-enumerable-property-symbols": "2.0.1",
"is-obj": "1.0.1",
"is-regexp": "1.0.0"
}
},
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
@ -2912,6 +3614,12 @@
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
},
"strip-indent": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
"integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
"dev": true
},
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
@ -2935,6 +3643,12 @@
"upper-case": "1.1.3"
}
},
"symbol-observable": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz",
"integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=",
"dev": true
},
"tedious": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/tedious/-/tedious-2.1.5.tgz",

View File

@ -1,65 +1,79 @@
{
"name": "typeorm-model-generator",
"version": "0.2.6",
"description": "Generates models for TypeORM from existing databases.",
"bin": "bin/typeorm-model-generator",
"scripts": {
"tsc:w": "tsc -w",
"tsc": "tsc",
"typings-install": "typings install",
"setup": "npm install && npm run typings-install",
"prestart": "tsc",
"start": " node ./dist/src/index.js",
"test": "istanbul cover ./node_modules/mocha/bin/_mocha dist/test/**/*.test.js -- -R spec",
"posttest": "remap-istanbul -i ./coverage/coverage.json -o ./coverage/coverage-remapped.json && codecov --file=./coverage/coverage-remapped.json "
},
"repository": {
"type": "git",
"url": "git+https://github.com/Kononnable/typeorm-model-generator.git"
},
"author": "Kononnable",
"license": "MIT",
"bugs": {
"url": "https://github.com/Kononnable/typeorm-model-generator/issues"
},
"homepage": "https://github.com/Kononnable/typeorm-model-generator#readme",
"dependencies": {
"handlebars": "^4.0.11",
"mssql": "^4.0.4",
"mysql": "^2.15.0",
"oracledb": "^2.0.15",
"pg": "^7.4.0",
"reflect-metadata": "^0.1.10",
"typeorm": "^0.2.0-alpha.13",
"change-case": "^3.0.1",
"typescript": "^2.6.1",
"yargs": "^11.0.0",
"yn": "^2.0.0"
},
"devDependencies": {
"@types/chai": "^4.0.5",
"@types/chai-as-promised": "7.1.0",
"@types/chai-subset": "^1.3.1",
"@types/fs-extra": "^5.0.0",
"@types/handlebars": "^4.0.36",
"@types/mocha": "^2.2.44",
"@types/mssql": "^4.0.4",
"@types/mysql": "2.15.2",
"@types/oracledb": "^1.11.34",
"@types/node": "^9.3.0",
"@types/pg": "^7.4.1",
"@types/sinon": "^4.1.2",
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"chai-subset": "^1.6.0",
"codecov": "^3.0.0",
"dotenv": "^5.0.0",
"fs-extra": "^5.0.0",
"istanbul": "^0.4.5",
"mocha": "^5.0.0",
"remap-istanbul": "^0.10.0",
"sinon": "^4.1.2",
"sinon-chai": "^2.14.0",
"typings": "^2.1.1"
}
"name": "typeorm-model-generator",
"version": "0.2.6",
"description": "Generates models for TypeORM from existing databases.",
"bin": "bin/typeorm-model-generator",
"scripts": {
"tsc:w": "tsc -w",
"tsc": "tsc",
"typings-install": "typings install",
"setup": "npm install && npm run typings-install",
"prestart": "tsc",
"start": " node ./dist/src/index.js",
"test": "istanbul cover ./node_modules/mocha/bin/_mocha dist/test/**/*.test.js -- -R spec",
"posttest": "remap-istanbul -i ./coverage/coverage.json -o ./coverage/coverage-remapped.json && codecov --file=./coverage/coverage-remapped.json "
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{ts,json,md}": [
"prettier --write",
"git add"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/Kononnable/typeorm-model-generator.git"
},
"author": "Kononnable",
"license": "MIT",
"bugs": {
"url": "https://github.com/Kononnable/typeorm-model-generator/issues"
},
"homepage": "https://github.com/Kononnable/typeorm-model-generator#readme",
"dependencies": {
"handlebars": "^4.0.11",
"mssql": "^4.0.4",
"mysql": "^2.15.0",
"oracledb": "^2.0.15",
"pg": "^7.4.0",
"reflect-metadata": "^0.1.10",
"typeorm": "^0.2.0-alpha.13",
"change-case": "^3.0.1",
"typescript": "^2.6.1",
"yargs": "^11.0.0",
"yn": "^2.0.0"
},
"devDependencies": {
"@types/chai": "^4.0.5",
"@types/chai-as-promised": "7.1.0",
"@types/chai-subset": "^1.3.1",
"@types/fs-extra": "^5.0.0",
"@types/handlebars": "^4.0.36",
"@types/mocha": "^2.2.44",
"@types/mssql": "^4.0.4",
"@types/mysql": "2.15.2",
"@types/node": "^9.3.0",
"@types/oracledb": "^1.11.34",
"@types/pg": "^7.4.1",
"@types/sinon": "^4.1.2",
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"chai-subset": "^1.6.0",
"codecov": "^3.0.0",
"dotenv": "^5.0.0",
"fs-extra": "^5.0.0",
"husky": "^0.14.3",
"istanbul": "^0.4.5",
"lint-staged": "^6.1.0",
"mocha": "^5.0.0",
"prettier": "^1.10.2",
"remap-istanbul": "^0.10.0",
"sinon": "^4.1.2",
"sinon-chai": "^2.14.0",
"typings": "^2.1.1"
}
}

View File

@ -1,136 +1,172 @@
import { AbstractDriver } from "./drivers/AbstractDriver";
import { DatabaseModel } from './models/DatabaseModel'
import * as Handlebars from 'handlebars'
import fs = require('fs');
import path = require('path')
import * as TomgUtils from './Utils'
import { DatabaseModel } from "./models/DatabaseModel";
import * as Handlebars from "handlebars";
import fs = require("fs");
import path = require("path");
import * as TomgUtils from "./Utils";
import changeCase = require("change-case");
/**
* Engine
*/
export class Engine {
constructor(private driver: AbstractDriver, public Options: EngineOptions) {
}
constructor(
private driver: AbstractDriver,
public Options: EngineOptions
) {}
public async createModelFromDatabase(): Promise<boolean> {
let dbModel = await this.getEntitiesInfo(this.Options.databaseName, this.Options.host, this.Options.port, this.Options.user, this.Options.password, this.Options.schemaName, this.Options.ssl);
let dbModel = await this.getEntitiesInfo(
this.Options.databaseName,
this.Options.host,
this.Options.port,
this.Options.user,
this.Options.password,
this.Options.schemaName,
this.Options.ssl
);
if (dbModel.entities.length > 0) {
this.createModelFromMetadata(dbModel);
} else {
TomgUtils.LogFatalError('Tables not found in selected database. Skipping creation of typeorm model.', false);
TomgUtils.LogFatalError(
"Tables not found in selected database. Skipping creation of typeorm model.",
false
);
}
return true;
}
private async getEntitiesInfo(database: string, server: string, port: number, user: string, password: string, schemaName: string, ssl: boolean): Promise<DatabaseModel> {
return await this.driver.GetDataFromServer(database, server, port, user, password, schemaName, ssl)
private async getEntitiesInfo(
database: string,
server: string,
port: number,
user: string,
password: string,
schemaName: string,
ssl: boolean
): Promise<DatabaseModel> {
return await this.driver.GetDataFromServer(
database,
server,
port,
user,
password,
schemaName,
ssl
);
}
private createModelFromMetadata(databaseModel: DatabaseModel) {
this.createHandlebarsHelpers();
let templatePath = path.resolve(__dirname, '../../src/entity.mst')
let template = fs.readFileSync(templatePath, 'UTF-8');
let resultPath = this.Options.resultsPath
if (!fs.existsSync(resultPath))
fs.mkdirSync(resultPath);
let entitesPath = resultPath
let templatePath = path.resolve(__dirname, "../../src/entity.mst");
let template = fs.readFileSync(templatePath, "UTF-8");
let resultPath = this.Options.resultsPath;
if (!fs.existsSync(resultPath)) fs.mkdirSync(resultPath);
let entitesPath = resultPath;
if (!this.Options.noConfigs) {
this.createTsConfigFile(resultPath)
this.createTypeOrmConfig(resultPath)
entitesPath = path.resolve(resultPath, './entities')
if (!fs.existsSync(entitesPath))
fs.mkdirSync(entitesPath);
this.createTsConfigFile(resultPath);
this.createTypeOrmConfig(resultPath);
entitesPath = path.resolve(resultPath, "./entities");
if (!fs.existsSync(entitesPath)) fs.mkdirSync(entitesPath);
}
let compliedTemplate = Handlebars.compile(template, { noEscape: true })
let compliedTemplate = Handlebars.compile(template, { noEscape: true });
databaseModel.entities.forEach(element => {
element.Imports = [];
element.Columns.forEach((column) => {
column.relations.forEach(
(relation) => {
if (element.EntityName !== relation.relatedTable) { element.Imports.push(relation.relatedTable); }
element.Columns.forEach(column => {
column.relations.forEach(relation => {
if (element.EntityName !== relation.relatedTable) {
element.Imports.push(relation.relatedTable);
}
);
});
});
element.Imports.filter(function (elem, index, self) {
element.Imports.filter(function(elem, index, self) {
return index === self.indexOf(elem);
});
let casedFileName = ''
let casedFileName = "";
switch (this.Options.convertCaseFile) {
case 'camel':
case "camel":
casedFileName = changeCase.camelCase(element.EntityName);
break;
case 'param':
case "param":
casedFileName = changeCase.paramCase(element.EntityName);
break;
case 'pascal':
case "pascal":
casedFileName = changeCase.pascalCase(element.EntityName);
break;
case 'none':
case "none":
casedFileName = element.EntityName;
break;
}
let resultFilePath = path.resolve(entitesPath, (casedFileName) + '.ts');
let rendered = compliedTemplate(element)
fs.writeFileSync(resultFilePath, rendered, { encoding: 'UTF-8', flag: 'w' })
let resultFilePath = path.resolve(
entitesPath,
casedFileName + ".ts"
);
let rendered = compliedTemplate(element);
fs.writeFileSync(resultFilePath, rendered, {
encoding: "UTF-8",
flag: "w"
});
});
}
private createHandlebarsHelpers() {
Handlebars.registerHelper("curly", (open) => { return open ? "{" : "}"; });
Handlebars.registerHelper("curly", open => {
return open ? "{" : "}";
});
Handlebars.registerHelper("toEntityName", str => {
let retStr = ''
let retStr = "";
switch (this.Options.convertCaseEntity) {
case 'camel':
case "camel":
retStr = changeCase.camelCase(str);
break;
case 'pascal':
case "pascal":
retStr = changeCase.pascalCase(str);
break;
case 'none':
case "none":
retStr = str;
break;
}
return retStr;
});
Handlebars.registerHelper("toFileName", str => {
let retStr = ''
let retStr = "";
switch (this.Options.convertCaseFile) {
case 'camel':
case "camel":
retStr = changeCase.camelCase(str);
break;
case 'param':
case "param":
retStr = changeCase.paramCase(str);
break;
case 'pascal':
case "pascal":
retStr = changeCase.pascalCase(str);
break;
case 'none':
case "none":
retStr = str;
break;
}
return retStr;
});
Handlebars.registerHelper("toPropertyName", str => {
let retStr = ''
let retStr = "";
switch (this.Options.convertCaseProperty) {
case 'camel':
case "camel":
retStr = changeCase.camelCase(str);
break;
case 'pascal':
case "pascal":
retStr = changeCase.pascalCase(str);
break;
case 'none':
case "none":
retStr = str;
break;
}
return retStr;
});
Handlebars.registerHelper('toLowerCase', str => {
Handlebars.registerHelper("toLowerCase", str => {
return str.toLowerCase();
});
}
//TODO:Move to mustache template file
private createTsConfigFile(resultPath) {
fs.writeFileSync(path.resolve(resultPath, 'tsconfig.json'), `{"compilerOptions": {
fs.writeFileSync(
path.resolve(resultPath, "tsconfig.json"),
`{"compilerOptions": {
"lib": ["es5", "es6"],
"target": "es6",
"module": "commonjs",
@ -138,11 +174,15 @@ export class Engine {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true
}}`, { encoding: 'UTF-8', flag: 'w' });
}}`,
{ encoding: "UTF-8", flag: "w" }
);
}
private createTypeOrmConfig(resultPath) {
if (this.Options.schemaName == '') {
fs.writeFileSync(path.resolve(resultPath, 'ormconfig.json'), `[
if (this.Options.schemaName == "") {
fs.writeFileSync(
path.resolve(resultPath, "ormconfig.json"),
`[
{
"name": "default",
"type": "${this.Options.databaseType}",
@ -156,10 +196,13 @@ export class Engine {
"entities/*.js"
]
}
]`, { encoding: 'UTF-8', flag: 'w' });
}
else {
fs.writeFileSync(path.resolve(resultPath, 'ormconfig.json'), `[
]`,
{ encoding: "UTF-8", flag: "w" }
);
} else {
fs.writeFileSync(
path.resolve(resultPath, "ormconfig.json"),
`[
{
"name": "default",
"type": "${this.Options.databaseType}",
@ -174,24 +217,24 @@ export class Engine {
"entities/*.js"
]
}
]`, { encoding: 'UTF-8', flag: 'w' });
]`,
{ encoding: "UTF-8", flag: "w" }
);
}
}
}
export interface EngineOptions {
host: string,
port: number,
databaseName: string,
user: string,
password: string,
resultsPath: string,
databaseType: string,
schemaName: string,
ssl: boolean,
noConfigs: boolean,
convertCaseFile: 'pascal' | 'param' | 'camel' | 'none',
convertCaseEntity: 'pascal' | 'camel' | 'none',
convertCaseProperty: 'pascal' | 'camel' | 'none',
host: string;
port: number;
databaseName: string;
user: string;
password: string;
resultsPath: string;
databaseType: string;
schemaName: string;
ssl: boolean;
noConfigs: boolean;
convertCaseFile: "pascal" | "param" | "camel" | "none";
convertCaseEntity: "pascal" | "camel" | "none";
convertCaseProperty: "pascal" | "camel" | "none";
}

View File

@ -1,13 +1,20 @@
import * as data from './../../package.json'
export function LogFatalError(errText: string, isABug: boolean = true, errObject?: any) {
import * as data from "./../../package.json";
export function LogFatalError(
errText: string,
isABug: boolean = true,
errObject?: any
) {
let x = <any>data;
console.error(errText)
console.error(`Fatal error occured.`)
console.error(`${x.name}@${x.version} node@${process.version}`)
console.error(`Fatal error occured in typeorm-model-generator.`)
console.error(`If this is a bug please open an issue including this log on ${x.bugs.url}`)
if (isABug && !errObject) errObject = new Error().stack
if (!!errObject) console.error(errObject)
process.abort()
console.error(errText);
console.error(`Fatal error occured.`);
console.error(`${x.name}@${x.version} node@${process.version}`);
console.error(`Fatal error occured in typeorm-model-generator.`);
console.error(
`If this is a bug please open an issue including this log on ${
x.bugs.url
}`
);
if (isABug && !errObject) errObject = new Error().stack;
if (!!errObject) console.error(errObject);
process.abort();
}

View File

@ -1,10 +1,18 @@
import { EntityInfo } from './../models/EntityInfo'
import { DatabaseModel } from './../models/DatabaseModel'
import { EntityInfo } from "./../models/EntityInfo";
import { DatabaseModel } from "./../models/DatabaseModel";
/**
* AbstractDriver
*/
export abstract class AbstractDriver {
async GetDataFromServer(database: string, server: string, port: number, user: string, password: string, schema: string, ssl: boolean): Promise<DatabaseModel> {
async GetDataFromServer(
database: string,
server: string,
port: number,
user: string,
password: string,
schema: string,
ssl: boolean
): Promise<DatabaseModel> {
let dbModel = <DatabaseModel>{};
await this.ConnectToServer(database, server, port, user, password, ssl);
dbModel.entities = await this.GetAllTables(schema);
@ -12,14 +20,30 @@ export abstract class AbstractDriver {
await this.GetIndexesFromEntity(dbModel.entities, schema);
dbModel.entities = await this.GetRelations(dbModel.entities, schema);
await this.DisconnectFromServer();
this.FindPrimaryColumnsFromIndexes(dbModel)
this.FindPrimaryColumnsFromIndexes(dbModel);
return dbModel;
}
abstract async ConnectToServer(database: string, server: string, port: number, user: string, password: string, ssl: boolean);
abstract async GetAllTables(schema: string): Promise<EntityInfo[]>
abstract async GetCoulmnsFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]>;
abstract async GetIndexesFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]>;
abstract async GetRelations(entities: EntityInfo[], schema: string): Promise<EntityInfo[]>;
abstract async ConnectToServer(
database: string,
server: string,
port: number,
user: string,
password: string,
ssl: boolean
);
abstract async GetAllTables(schema: string): Promise<EntityInfo[]>;
abstract async GetCoulmnsFromEntity(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]>;
abstract async GetIndexesFromEntity(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]>;
abstract async GetRelations(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]>;
abstract async FindPrimaryColumnsFromIndexes(dbModel: DatabaseModel);
abstract async DisconnectFromServer();

View File

@ -1,14 +1,13 @@
import { AbstractDriver } from './AbstractDriver'
import * as MariaDb from 'mysql'
import { ColumnInfo } from './../models/ColumnInfo'
import { EntityInfo } from './../models/EntityInfo'
import { RelationInfo } from './../models/RelationInfo'
import { DatabaseModel } from './../models/DatabaseModel'
import { MysqlDriver } from './MysqlDriver';
import { AbstractDriver } from "./AbstractDriver";
import * as MariaDb from "mysql";
import { ColumnInfo } from "./../models/ColumnInfo";
import { EntityInfo } from "./../models/EntityInfo";
import { RelationInfo } from "./../models/RelationInfo";
import { DatabaseModel } from "./../models/DatabaseModel";
import { MysqlDriver } from "./MysqlDriver";
/**
* MariaDb
*/
export class MariaDbDriver extends MysqlDriver {
readonly EngineName: string = 'MariaDb'
readonly EngineName: string = "MariaDb";
}

View File

@ -1,10 +1,10 @@
import { AbstractDriver } from './AbstractDriver'
import * as MSSQL from 'mssql'
import { ColumnInfo } from './../models/ColumnInfo'
import { EntityInfo } from './../models/EntityInfo'
import { RelationInfo } from './../models/RelationInfo'
import { DatabaseModel } from './../models/DatabaseModel'
import * as TomgUtils from './../Utils'
import { AbstractDriver } from "./AbstractDriver";
import * as MSSQL from "mssql";
import { ColumnInfo } from "./../models/ColumnInfo";
import { EntityInfo } from "./../models/EntityInfo";
import { RelationInfo } from "./../models/RelationInfo";
import { DatabaseModel } from "./../models/DatabaseModel";
import * as TomgUtils from "./../Utils";
/**
* MssqlDriver
@ -14,204 +14,277 @@ export class MssqlDriver extends AbstractDriver {
dbModel.entities.forEach(entity => {
let primaryIndex = entity.Indexes.find(v => v.isPrimaryKey);
if (!primaryIndex) {
TomgUtils.LogFatalError(`Table ${entity.EntityName} has no PK.`, false)
TomgUtils.LogFatalError(
`Table ${entity.EntityName} has no PK.`,
false
);
return;
}
entity.Columns.forEach(col => {
if (primaryIndex!.columns.some(cIndex => cIndex.name == col.name)) col.isPrimary = true
})
if (
primaryIndex!.columns.some(
cIndex => cIndex.name == col.name
)
)
col.isPrimary = true;
});
});
}
async GetAllTables(schema: string): Promise<EntityInfo[]> {
let request = new MSSQL.Request(this.Connection)
let response: { TABLE_SCHEMA: string, TABLE_NAME: string }[]
= (await request.query(`SELECT TABLE_SCHEMA,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA='${schema}'`)).recordset;
let request = new MSSQL.Request(this.Connection);
let response: {
TABLE_SCHEMA: string;
TABLE_NAME: string;
}[] = (await request.query(
`SELECT TABLE_SCHEMA,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA='${schema}'`
)).recordset;
let ret: EntityInfo[] = <EntityInfo[]>[];
response.forEach((val) => {
response.forEach(val => {
let ent: EntityInfo = new EntityInfo();
ent.EntityName = val.TABLE_NAME;
ent.Columns = <ColumnInfo[]>[];
ent.Indexes = <IndexInfo[]>[];
ret.push(ent);
})
});
return ret;
}
async GetCoulmnsFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
let request = new MSSQL.Request(this.Connection)
async GetCoulmnsFromEntity(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let request = new MSSQL.Request(this.Connection);
let response: {
TABLE_NAME: string, COLUMN_NAME: string, COLUMN_DEFAULT: string,
IS_NULLABLE: string, DATA_TYPE: string, CHARACTER_MAXIMUM_LENGTH: number,
NUMERIC_PRECISION: number, NUMERIC_SCALE: number, IsIdentity: number
}[]
= (await request.query(`SELECT TABLE_NAME,COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE,
TABLE_NAME: string;
COLUMN_NAME: string;
COLUMN_DEFAULT: string;
IS_NULLABLE: string;
DATA_TYPE: string;
CHARACTER_MAXIMUM_LENGTH: number;
NUMERIC_PRECISION: number;
NUMERIC_SCALE: number;
IsIdentity: number;
}[] = (await request.query(`SELECT TABLE_NAME,COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE,
DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION,NUMERIC_SCALE,
COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') IsIdentity FROM INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA='${schema}'`)).recordset;
entities.forEach((ent) => {
response.filter((filterVal) => {
return filterVal.TABLE_NAME == ent.EntityName;
}).forEach((resp) => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.name = resp.COLUMN_NAME;
colInfo.is_nullable = resp.IS_NULLABLE == 'YES' ? true : false;
colInfo.is_generated = resp.IsIdentity == 1 ? true : false;
colInfo.default = resp.COLUMN_DEFAULT;
switch (resp.DATA_TYPE) {
case "int":
colInfo.ts_type = "number"
colInfo.sql_type = "int"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "tinyint":
colInfo.ts_type = "number"
colInfo.sql_type = "smallint"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "smallint":
colInfo.ts_type = "number"
colInfo.sql_type = "smallint"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "bit":
colInfo.ts_type = "boolean"
colInfo.sql_type = "boolean"
break;
case "float":
colInfo.ts_type = "number"
colInfo.sql_type = "float"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
colInfo.numericPrecision = resp.NUMERIC_PRECISION
break;
case "bigint":
colInfo.ts_type = "string"
colInfo.sql_type = "bigint"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "date":
colInfo.ts_type = "Date"
colInfo.sql_type = "date"
break;
case "time":
colInfo.ts_type = "Date"
colInfo.sql_type = "time"
break;
case "datetime":
colInfo.ts_type = "Date";
colInfo.sql_type = "datetime"
break;
case "char":
colInfo.ts_type = "string"
colInfo.sql_type = "char"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "nchar":
colInfo.ts_type = "string"
colInfo.sql_type = "nchar"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "text":
colInfo.ts_type = "string"
colInfo.sql_type = "text"
break;
case "ntext":
colInfo.ts_type = "string"
colInfo.sql_type = "ntext"
break;
case "uniqueidentifier":
colInfo.ts_type = "string"
colInfo.sql_type = "uniqueidentifier"
break;
case "varchar":
colInfo.ts_type = "string"
colInfo.sql_type = "varchar"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "binary":
colInfo.ts_type = "Buffer"
colInfo.sql_type = "binary"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "varbinary":
colInfo.ts_type = "Buffer"
colInfo.sql_type = "varbinary"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "image":
colInfo.ts_type = "Buffer"
colInfo.sql_type = "image"
break;
case "nvarchar":
colInfo.ts_type = "string"
colInfo.sql_type = "nvarchar"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "money":
colInfo.ts_type = "number"
colInfo.sql_type = "decimal"
break;
case "smallmoney":
colInfo.ts_type = "number"
colInfo.sql_type = "smallmoney"
break;
case "real":
colInfo.ts_type = "number"
colInfo.sql_type = "double"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "decimal":
colInfo.ts_type = "number"
colInfo.sql_type = "decimal"
colInfo.numericPrecision = resp.NUMERIC_PRECISION
colInfo.numericScale = resp.NUMERIC_SCALE
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "numeric":
colInfo.ts_type = "number"
colInfo.sql_type = "numeric"
colInfo.numericPrecision = resp.NUMERIC_PRECISION
colInfo.numericScale = resp.NUMERIC_SCALE
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "datetime2":
colInfo.ts_type = "Date"
colInfo.sql_type = "datetime2"
colInfo.numericPrecision = resp.NUMERIC_PRECISION
break;
case "time":
colInfo.ts_type = "Date"
colInfo.sql_type = "time"
colInfo.numericPrecision = resp.NUMERIC_PRECISION
break;
case "datetimeoffset":
colInfo.ts_type = "Date"
colInfo.sql_type = "datetimeoffset"
colInfo.numericPrecision = resp.NUMERIC_PRECISION
break;
case "smalldatetime":
colInfo.ts_type = "Date"
colInfo.sql_type = "smalldatetime"
break;
case "xml":
colInfo.ts_type = "string"
colInfo.sql_type = "text"
break;
default:
TomgUtils.LogFatalError("Unknown column type:" + resp.DATA_TYPE);
break;
}
COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') IsIdentity FROM INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA='${schema}'`))
.recordset;
entities.forEach(ent => {
response
.filter(filterVal => {
return filterVal.TABLE_NAME == ent.EntityName;
})
.forEach(resp => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.name = resp.COLUMN_NAME;
colInfo.is_nullable =
resp.IS_NULLABLE == "YES" ? true : false;
colInfo.is_generated = resp.IsIdentity == 1 ? true : false;
colInfo.default = resp.COLUMN_DEFAULT;
switch (resp.DATA_TYPE) {
case "int":
colInfo.ts_type = "number";
colInfo.sql_type = "int";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "tinyint":
colInfo.ts_type = "number";
colInfo.sql_type = "smallint";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "smallint":
colInfo.ts_type = "number";
colInfo.sql_type = "smallint";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "bit":
colInfo.ts_type = "boolean";
colInfo.sql_type = "boolean";
break;
case "float":
colInfo.ts_type = "number";
colInfo.sql_type = "float";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
colInfo.numericPrecision = resp.NUMERIC_PRECISION;
break;
case "bigint":
colInfo.ts_type = "string";
colInfo.sql_type = "bigint";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "date":
colInfo.ts_type = "Date";
colInfo.sql_type = "date";
break;
case "time":
colInfo.ts_type = "Date";
colInfo.sql_type = "time";
break;
case "datetime":
colInfo.ts_type = "Date";
colInfo.sql_type = "datetime";
break;
case "char":
colInfo.ts_type = "string";
colInfo.sql_type = "char";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "nchar":
colInfo.ts_type = "string";
colInfo.sql_type = "nchar";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "text":
colInfo.ts_type = "string";
colInfo.sql_type = "text";
break;
case "ntext":
colInfo.ts_type = "string";
colInfo.sql_type = "ntext";
break;
case "uniqueidentifier":
colInfo.ts_type = "string";
colInfo.sql_type = "uniqueidentifier";
break;
case "varchar":
colInfo.ts_type = "string";
colInfo.sql_type = "varchar";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "binary":
colInfo.ts_type = "Buffer";
colInfo.sql_type = "binary";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "varbinary":
colInfo.ts_type = "Buffer";
colInfo.sql_type = "varbinary";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "image":
colInfo.ts_type = "Buffer";
colInfo.sql_type = "image";
break;
case "nvarchar":
colInfo.ts_type = "string";
colInfo.sql_type = "nvarchar";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "money":
colInfo.ts_type = "number";
colInfo.sql_type = "decimal";
break;
case "smallmoney":
colInfo.ts_type = "number";
colInfo.sql_type = "smallmoney";
break;
case "real":
colInfo.ts_type = "number";
colInfo.sql_type = "double";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "decimal":
colInfo.ts_type = "number";
colInfo.sql_type = "decimal";
colInfo.numericPrecision = resp.NUMERIC_PRECISION;
colInfo.numericScale = resp.NUMERIC_SCALE;
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "numeric":
colInfo.ts_type = "number";
colInfo.sql_type = "numeric";
colInfo.numericPrecision = resp.NUMERIC_PRECISION;
colInfo.numericScale = resp.NUMERIC_SCALE;
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "datetime2":
colInfo.ts_type = "Date";
colInfo.sql_type = "datetime2";
colInfo.numericPrecision = resp.NUMERIC_PRECISION;
break;
case "time":
colInfo.ts_type = "Date";
colInfo.sql_type = "time";
colInfo.numericPrecision = resp.NUMERIC_PRECISION;
break;
case "datetimeoffset":
colInfo.ts_type = "Date";
colInfo.sql_type = "datetimeoffset";
colInfo.numericPrecision = resp.NUMERIC_PRECISION;
break;
case "smalldatetime":
colInfo.ts_type = "Date";
colInfo.sql_type = "smalldatetime";
break;
case "xml":
colInfo.ts_type = "string";
colInfo.sql_type = "text";
break;
default:
TomgUtils.LogFatalError(
"Unknown column type:" + resp.DATA_TYPE
);
break;
}
if (colInfo.sql_type) ent.Columns.push(colInfo);
})
})
if (colInfo.sql_type) ent.Columns.push(colInfo);
});
});
return entities;
}
async GetIndexesFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
let request = new MSSQL.Request(this.Connection)
async GetIndexesFromEntity(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let request = new MSSQL.Request(this.Connection);
let response: {
TableName: string, IndexName: string, ColumnName: string, is_unique: number,
is_primary_key: number//, is_descending_key: number//, is_included_column: number
}[]
= (await request.query(`SELECT
TableName: string;
IndexName: string;
ColumnName: string;
is_unique: number;
is_primary_key: number; //, is_descending_key: number//, is_included_column: number
}[] = (await request.query(`SELECT
TableName = t.name,
IndexName = ind.name,
ColumnName = col.name,
@ -233,44 +306,54 @@ WHERE
t.is_ms_shipped = 0 and s.name='${schema}'
ORDER BY
t.name, ind.name, ind.index_id, ic.key_ordinal;`)).recordset;
entities.forEach((ent) => {
response.filter((filterVal) => {
return filterVal.TableName == ent.EntityName;
}).forEach((resp) => {
let indexInfo: IndexInfo = <IndexInfo>{};
let indexColumnInfo: IndexColumnInfo = <IndexColumnInfo>{};
if (ent.Indexes.filter((filterVal) => {
return filterVal.name == resp.IndexName
}).length > 0) {
indexInfo = ent.Indexes.filter((filterVal) => {
return filterVal.name == resp.IndexName
})[0];
} else {
indexInfo.columns = <IndexColumnInfo[]>[];
indexInfo.name = resp.IndexName;
indexInfo.isUnique = resp.is_unique == 1 ? true : false;
indexInfo.isPrimaryKey = resp.is_primary_key == 1 ? true : false;
ent.Indexes.push(indexInfo);
}
indexColumnInfo.name = resp.ColumnName;
// indexColumnInfo.isIncludedColumn = resp.is_included_column == 1 ? true : false;
// indexColumnInfo.isDescending = resp.is_descending_key == 1 ? true : false;
indexInfo.columns.push(indexColumnInfo);
})
})
entities.forEach(ent => {
response
.filter(filterVal => {
return filterVal.TableName == ent.EntityName;
})
.forEach(resp => {
let indexInfo: IndexInfo = <IndexInfo>{};
let indexColumnInfo: IndexColumnInfo = <IndexColumnInfo>{};
if (
ent.Indexes.filter(filterVal => {
return filterVal.name == resp.IndexName;
}).length > 0
) {
indexInfo = ent.Indexes.filter(filterVal => {
return filterVal.name == resp.IndexName;
})[0];
} else {
indexInfo.columns = <IndexColumnInfo[]>[];
indexInfo.name = resp.IndexName;
indexInfo.isUnique = resp.is_unique == 1 ? true : false;
indexInfo.isPrimaryKey =
resp.is_primary_key == 1 ? true : false;
ent.Indexes.push(indexInfo);
}
indexColumnInfo.name = resp.ColumnName;
// indexColumnInfo.isIncludedColumn = resp.is_included_column == 1 ? true : false;
// indexColumnInfo.isDescending = resp.is_descending_key == 1 ? true : false;
indexInfo.columns.push(indexColumnInfo);
});
});
return entities;
}
async GetRelations(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
let request = new MSSQL.Request(this.Connection)
async GetRelations(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let request = new MSSQL.Request(this.Connection);
let response: {
TableWithForeignKey: string, FK_PartNo: number, ForeignKeyColumn: string,
TableReferenced: string, ForeignKeyColumnReferenced: string,
onDelete: "RESTRICT" | "CASCADE" | "SET NULL",
onUpdate: "RESTRICT" | "CASCADE" | "SET NULL", object_id: number
}[]
= (await request.query(`select
TableWithForeignKey: string;
FK_PartNo: number;
ForeignKeyColumn: string;
TableReferenced: string;
ForeignKeyColumnReferenced: string;
onDelete: "RESTRICT" | "CASCADE" | "SET NULL";
onUpdate: "RESTRICT" | "CASCADE" | "SET NULL";
object_id: number;
}[] = (await request.query(`select
parentTable.name as TableWithForeignKey,
fkc.constraint_column_id as FK_PartNo,
parentColumn.name as ForeignKeyColumn,
@ -298,10 +381,10 @@ where
order by
TableWithForeignKey, FK_PartNo`)).recordset;
let relationsTemp: RelationTempInfo[] = <RelationTempInfo[]>[];
response.forEach((resp) => {
let rels = relationsTemp.find((val) => {
response.forEach(resp => {
let rels = relationsTemp.find(val => {
return val.object_id == resp.object_id;
})
});
if (rels == undefined) {
rels = <RelationTempInfo>{};
rels.ownerColumnsNames = [];
@ -315,112 +398,148 @@ order by
}
rels.ownerColumnsNames.push(resp.ForeignKeyColumn);
rels.referencedColumnsNames.push(resp.ForeignKeyColumnReferenced);
})
relationsTemp.forEach((relationTmp) => {
let ownerEntity = entities.find((entitity) => {
});
relationsTemp.forEach(relationTmp => {
let ownerEntity = entities.find(entitity => {
return entitity.EntityName == relationTmp.ownerTable;
})
});
if (!ownerEntity) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity model ${relationTmp.ownerTable}.`
);
return;
}
let referencedEntity = entities.find((entitity) => {
let referencedEntity = entities.find(entitity => {
return entitity.EntityName == relationTmp.referencedTable;
})
});
if (!referencedEntity) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity model ${relationTmp.referencedTable}.`
);
return;
}
let ownerColumn = ownerEntity.Columns.find((column) => {
let ownerColumn = ownerEntity.Columns.find(column => {
return column.name == relationTmp.ownerColumnsNames[0];
})
});
if (!ownerColumn) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity column ${
relationTmp.ownerTable
}.${ownerColumn}.`
);
return;
}
let relatedColumn = referencedEntity.Columns.find((column) => {
let relatedColumn = referencedEntity.Columns.find(column => {
return column.name == relationTmp.referencedColumnsNames[0];
})
});
if (!relatedColumn) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity column ${
relationTmp.referencedTable
}.${relatedColumn}.`
);
return;
}
let ownColumn: ColumnInfo = ownerColumn;
let isOneToMany: boolean;
isOneToMany = false;
let index = ownerEntity.Indexes.find(
(index) => {
return index.isUnique && index.columns.some(col => {
return col.name == ownerColumn!.name
let index = ownerEntity.Indexes.find(index => {
return (
index.isUnique &&
index.columns.some(col => {
return col.name == ownerColumn!.name;
})
}
)
);
});
if (!index) {
isOneToMany = true;
} else {
isOneToMany = false;
}
let ownerRelation = new RelationInfo()
let columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '')
if (referencedEntity.Columns.filter((filterVal) => {
return filterVal.name == columnName;
}).length > 0) {
let ownerRelation = new RelationInfo();
let columnName =
ownerEntity.EntityName.toLowerCase() + (isOneToMany ? "s" : "");
if (
referencedEntity.Columns.filter(filterVal => {
return filterVal.name == columnName;
}).length > 0
) {
for (let i = 2; i <= ownerEntity.Columns.length; i++) {
columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '') + i.toString();
if (referencedEntity.Columns.filter((filterVal) => {
return filterVal.name == columnName;
}).length == 0) break;
columnName =
ownerEntity.EntityName.toLowerCase() +
(isOneToMany ? "s" : "") +
i.toString();
if (
referencedEntity.Columns.filter(filterVal => {
return filterVal.name == columnName;
}).length == 0
)
break;
}
}
ownerRelation.actionOnDelete = relationTmp.actionOnDelete
ownerRelation.actionOnUpdate = relationTmp.actionOnUpdate
ownerRelation.isOwner = true
ownerRelation.relatedColumn = relatedColumn.name.toLowerCase()
ownerRelation.relatedTable = relationTmp.referencedTable
ownerRelation.ownerTable = relationTmp.ownerTable
ownerRelation.ownerColumn = columnName
ownerRelation.relationType = isOneToMany ? "ManyToOne" : "OneToOne"
ownerColumn.relations.push(ownerRelation)
ownerRelation.actionOnDelete = relationTmp.actionOnDelete;
ownerRelation.actionOnUpdate = relationTmp.actionOnUpdate;
ownerRelation.isOwner = true;
ownerRelation.relatedColumn = relatedColumn.name.toLowerCase();
ownerRelation.relatedTable = relationTmp.referencedTable;
ownerRelation.ownerTable = relationTmp.ownerTable;
ownerRelation.ownerColumn = columnName;
ownerRelation.relationType = isOneToMany ? "ManyToOne" : "OneToOne";
ownerColumn.relations.push(ownerRelation);
if (isOneToMany) {
let col = new ColumnInfo()
col.name = columnName
let col = new ColumnInfo();
col.name = columnName;
let referencedRelation = new RelationInfo();
col.relations.push(referencedRelation)
referencedRelation.actionOnDelete = relationTmp.actionOnDelete
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate
referencedRelation.isOwner = false
referencedRelation.relatedColumn = ownerColumn.name
referencedRelation.relatedTable = relationTmp.ownerTable
referencedRelation.ownerTable = relationTmp.referencedTable
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase()
referencedRelation.relationType = "OneToMany"
referencedEntity.Columns.push(col)
col.relations.push(referencedRelation);
referencedRelation.actionOnDelete = relationTmp.actionOnDelete;
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate;
referencedRelation.isOwner = false;
referencedRelation.relatedColumn = ownerColumn.name;
referencedRelation.relatedTable = relationTmp.ownerTable;
referencedRelation.ownerTable = relationTmp.referencedTable;
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase();
referencedRelation.relationType = "OneToMany";
referencedEntity.Columns.push(col);
} else {
let col = new ColumnInfo()
col.name = columnName
let col = new ColumnInfo();
col.name = columnName;
let referencedRelation = new RelationInfo();
col.relations.push(referencedRelation)
referencedRelation.actionOnDelete = relationTmp.actionOnDelete
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate
referencedRelation.isOwner = false
referencedRelation.relatedColumn = ownerColumn.name
referencedRelation.relatedTable = relationTmp.ownerTable
referencedRelation.ownerTable = relationTmp.referencedTable
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase()
referencedRelation.relationType = "OneToOne"
col.relations.push(referencedRelation);
referencedRelation.actionOnDelete = relationTmp.actionOnDelete;
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate;
referencedRelation.isOwner = false;
referencedRelation.relatedColumn = ownerColumn.name;
referencedRelation.relatedTable = relationTmp.ownerTable;
referencedRelation.ownerTable = relationTmp.referencedTable;
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase();
referencedRelation.relationType = "OneToOne";
referencedEntity.Columns.push(col)
referencedEntity.Columns.push(col);
}
})
});
return entities;
}
async DisconnectFromServer() {
if (this.Connection)
await this.Connection.close();
if (this.Connection) await this.Connection.close();
}
private Connection: MSSQL.ConnectionPool;
async ConnectToServer(database: string, server: string, port: number, user: string, password: string, ssl: boolean) {
async ConnectToServer(
database: string,
server: string,
port: number,
user: string,
password: string,
ssl: boolean
) {
let config: MSSQL.config = {
database: database,
server: server,
@ -429,43 +548,45 @@ order by
password: password,
options: {
encrypt: ssl, // Use this if you're on Windows Azure
appName: 'typeorm-model-generator'
appName: "typeorm-model-generator"
}
}
};
let promise = new Promise<boolean>(
(resolve, reject) => {
this.Connection = new MSSQL.ConnectionPool(config, (err) => {
if (!err) {
//Connection successfull
resolve(true)
}
else {
TomgUtils.LogFatalError('Error connecting to MSSQL Server.', false, err.message)
reject(err)
}
});
}
)
let promise = new Promise<boolean>((resolve, reject) => {
this.Connection = new MSSQL.ConnectionPool(config, err => {
if (!err) {
//Connection successfull
resolve(true);
} else {
TomgUtils.LogFatalError(
"Error connecting to MSSQL Server.",
false,
err.message
);
reject(err);
}
});
});
await promise;
}
async CreateDB(dbName: string) {
let request = new MSSQL.Request(this.Connection);
let resp = await request.query(`CREATE DATABASE ${dbName}; `)
let resp = await request.query(`CREATE DATABASE ${dbName}; `);
}
async UseDB(dbName: string) {
let request = new MSSQL.Request(this.Connection);
let resp = await request.query(`USE ${dbName}; `)
let resp = await request.query(`USE ${dbName}; `);
}
async DropDB(dbName: string) {
let request = new MSSQL.Request(this.Connection);
let resp = await request.query(`DROP DATABASE ${dbName}; `)
let resp = await request.query(`DROP DATABASE ${dbName}; `);
}
async CheckIfDBExists(dbName: string): Promise<boolean> {
let request = new MSSQL.Request(this.Connection);
let resp = await request.query(`SELECT name FROM master.sys.databases WHERE name = N'${dbName}' `)
let resp = await request.query(
`SELECT name FROM master.sys.databases WHERE name = N'${dbName}' `
);
return resp.recordset.length > 0;
}
}

View File

@ -1,259 +1,330 @@
import { AbstractDriver } from './AbstractDriver'
import * as MYSQL from 'mysql'
import { ColumnInfo } from './../models/ColumnInfo'
import { EntityInfo } from './../models/EntityInfo'
import { RelationInfo } from './../models/RelationInfo'
import { DatabaseModel } from './../models/DatabaseModel'
import * as TomgUtils from './../Utils'
import { AbstractDriver } from "./AbstractDriver";
import * as MYSQL from "mysql";
import { ColumnInfo } from "./../models/ColumnInfo";
import { EntityInfo } from "./../models/EntityInfo";
import { RelationInfo } from "./../models/RelationInfo";
import { DatabaseModel } from "./../models/DatabaseModel";
import * as TomgUtils from "./../Utils";
/**
* MysqlDriver
*/
export class MysqlDriver extends AbstractDriver {
readonly EngineName: string = 'MySQL'
readonly EngineName: string = "MySQL";
FindPrimaryColumnsFromIndexes(dbModel: DatabaseModel) {
dbModel.entities.forEach(entity => {
let primaryIndex = entity.Indexes.find(v => v.isPrimaryKey);
if (!primaryIndex) {
TomgUtils.LogFatalError(`Table ${entity.EntityName} has no PK.`, false)
TomgUtils.LogFatalError(
`Table ${entity.EntityName} has no PK.`,
false
);
return;
}
entity.Columns.forEach(col => {
if (primaryIndex!.columns.some(cIndex => cIndex.name == col.name)) col.isPrimary = true
})
if (
primaryIndex!.columns.some(
cIndex => cIndex.name == col.name
)
)
col.isPrimary = true;
});
});
}
async GetAllTables(schema: string): Promise<EntityInfo[]> {
let response = await this.ExecQuery<{ TABLE_SCHEMA: string, TABLE_NAME: string }>(`SELECT TABLE_SCHEMA, TABLE_NAME
let response = await this.ExecQuery<{
TABLE_SCHEMA: string;
TABLE_NAME: string;
}>(`SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.tables
WHERE table_type='BASE TABLE'
AND table_schema like DATABASE()`);
let ret: EntityInfo[] = <EntityInfo[]>[];
response.forEach((val) => {
response.forEach(val => {
let ent: EntityInfo = new EntityInfo();
ent.EntityName = val.TABLE_NAME;
ent.Columns = <ColumnInfo[]>[];
ent.Indexes = <IndexInfo[]>[];
ret.push(ent);
})
});
return ret;
}
async GetCoulmnsFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
async GetCoulmnsFromEntity(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let response = await this.ExecQuery<{
TABLE_NAME: string, COLUMN_NAME: string, COLUMN_DEFAULT: string,
IS_NULLABLE: string, DATA_TYPE: string, CHARACTER_MAXIMUM_LENGTH: number,
NUMERIC_PRECISION: number, NUMERIC_SCALE: number, IsIdentity: number, column_type:string
TABLE_NAME: string;
COLUMN_NAME: string;
COLUMN_DEFAULT: string;
IS_NULLABLE: string;
DATA_TYPE: string;
CHARACTER_MAXIMUM_LENGTH: number;
NUMERIC_PRECISION: number;
NUMERIC_SCALE: number;
IsIdentity: number;
column_type: string;
}>(`SELECT TABLE_NAME,COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE,
DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION,NUMERIC_SCALE,
CASE WHEN EXTRA like '%auto_increment%' THEN 1 ELSE 0 END IsIdentity, column_type FROM INFORMATION_SCHEMA.COLUMNS
where TABLE_SCHEMA like DATABASE()`);
entities.forEach((ent) => {
response.filter((filterVal) => {
return filterVal.TABLE_NAME == ent.EntityName;
}).forEach((resp) => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.name = resp.COLUMN_NAME;
colInfo.is_nullable = resp.IS_NULLABLE == 'YES' ? true : false;
colInfo.is_generated = resp.IsIdentity == 1 ? true : false;
colInfo.default = resp.COLUMN_DEFAULT;
switch (resp.DATA_TYPE) {
case "int":
colInfo.ts_type = "number"
colInfo.sql_type = "int"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "tinyint":
colInfo.ts_type = "number"
colInfo.sql_type = "tinyint"
break;
case "smallint":
colInfo.ts_type = "number"
colInfo.sql_type = "smallint"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "bit":
colInfo.ts_type = "boolean"
colInfo.sql_type = "boolean"
break;
case "float":
colInfo.ts_type = "number"
colInfo.sql_type = "float"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "bigint":
colInfo.ts_type = "number"
colInfo.sql_type = "bigint"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "date":
colInfo.ts_type = "string"
colInfo.sql_type = "date"
break;
case "time":
colInfo.ts_type = "string"
colInfo.sql_type = "time"
break;
case "datetime":
colInfo.ts_type = "Date";
colInfo.sql_type = "datetime"
break;
case "char":
colInfo.ts_type = "string"
colInfo.sql_type = "text"
break;
case "nchar":
colInfo.ts_type = "string"
colInfo.sql_type = "text"
break;
case "text":
colInfo.ts_type = "string"
colInfo.sql_type = "text"
break;
case "ntext":
colInfo.ts_type = "string"
colInfo.sql_type = "text"
break;
entities.forEach(ent => {
response
.filter(filterVal => {
return filterVal.TABLE_NAME == ent.EntityName;
})
.forEach(resp => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.name = resp.COLUMN_NAME;
colInfo.is_nullable =
resp.IS_NULLABLE == "YES" ? true : false;
colInfo.is_generated = resp.IsIdentity == 1 ? true : false;
colInfo.default = resp.COLUMN_DEFAULT;
switch (resp.DATA_TYPE) {
case "int":
colInfo.ts_type = "number";
colInfo.sql_type = "int";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "tinyint":
colInfo.ts_type = "number";
colInfo.sql_type = "tinyint";
break;
case "smallint":
colInfo.ts_type = "number";
colInfo.sql_type = "smallint";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "bit":
colInfo.ts_type = "boolean";
colInfo.sql_type = "boolean";
break;
case "float":
colInfo.ts_type = "number";
colInfo.sql_type = "float";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "bigint":
colInfo.ts_type = "number";
colInfo.sql_type = "bigint";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "date":
colInfo.ts_type = "string";
colInfo.sql_type = "date";
break;
case "time":
colInfo.ts_type = "string";
colInfo.sql_type = "time";
break;
case "datetime":
colInfo.ts_type = "Date";
colInfo.sql_type = "datetime";
break;
case "char":
colInfo.ts_type = "string";
colInfo.sql_type = "text";
break;
case "nchar":
colInfo.ts_type = "string";
colInfo.sql_type = "text";
break;
case "text":
colInfo.ts_type = "string";
colInfo.sql_type = "text";
break;
case "ntext":
colInfo.ts_type = "string";
colInfo.sql_type = "text";
break;
case "mediumint":
colInfo.ts_type = "number"
colInfo.sql_type = "mediumint"
break;
case "timestamp":
colInfo.ts_type = "Date"
colInfo.sql_type = "timestamp"
break;
case "year":
colInfo.ts_type = "number"
colInfo.sql_type = "year"
break;
case "blob":
colInfo.ts_type = "Buffer"
colInfo.sql_type = "blob"
break;
case "tinyblob":
colInfo.ts_type = "Buffer"
colInfo.sql_type = "tinyblob"
break;
case "tinytext":
colInfo.ts_type = "string"
colInfo.sql_type = "tinytext"
break;
case "mediumblob":
colInfo.ts_type = "Buffer"
colInfo.sql_type = "mediumblob"
break;
case "mediumtext":
colInfo.ts_type = "string"
colInfo.sql_type = "mediumtext"
break;
case "longblob":
colInfo.ts_type = "Buffer"
colInfo.sql_type = "longblob"
break;
case "longtext":
colInfo.ts_type = "string"
colInfo.sql_type = "longtext"
break;
case "mediumint":
colInfo.ts_type = "number";
colInfo.sql_type = "mediumint";
break;
case "timestamp":
colInfo.ts_type = "Date";
colInfo.sql_type = "timestamp";
break;
case "year":
colInfo.ts_type = "number";
colInfo.sql_type = "year";
break;
case "blob":
colInfo.ts_type = "Buffer";
colInfo.sql_type = "blob";
break;
case "tinyblob":
colInfo.ts_type = "Buffer";
colInfo.sql_type = "tinyblob";
break;
case "tinytext":
colInfo.ts_type = "string";
colInfo.sql_type = "tinytext";
break;
case "mediumblob":
colInfo.ts_type = "Buffer";
colInfo.sql_type = "mediumblob";
break;
case "mediumtext":
colInfo.ts_type = "string";
colInfo.sql_type = "mediumtext";
break;
case "longblob":
colInfo.ts_type = "Buffer";
colInfo.sql_type = "longblob";
break;
case "longtext":
colInfo.ts_type = "string";
colInfo.sql_type = "longtext";
break;
case "varchar":
colInfo.ts_type = "string"
colInfo.sql_type = "varchar"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "nvarchar":
colInfo.ts_type = "string"
colInfo.sql_type = "nvarchar"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "money":
colInfo.ts_type = "number"
colInfo.sql_type = "decimal"
break;
case "real":
colInfo.ts_type = "number"
colInfo.sql_type = "double"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "double":
colInfo.ts_type = "number"
colInfo.sql_type = "double"
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "decimal":
colInfo.ts_type = "number"
colInfo.sql_type = "decimal"
colInfo.numericPrecision = resp.NUMERIC_PRECISION
colInfo.numericScale = resp.NUMERIC_SCALE
colInfo.char_max_lenght = resp.CHARACTER_MAXIMUM_LENGTH > 0 ? resp.CHARACTER_MAXIMUM_LENGTH : null;
break;
case "xml":
colInfo.ts_type = "string"
colInfo.sql_type = "text"
break;
case "json":
colInfo.ts_type = "Object"
colInfo.sql_type = "json"
break;
case "enum":
colInfo.ts_type = "string"
colInfo.sql_type = "enum"
colInfo.enumOptions = resp.column_type.substring(5, resp.column_type.length - 1).replace(/\'/gi,'"')
break;
default:
TomgUtils.LogFatalError("Unknown column type:" + resp.DATA_TYPE);
break;
}
if (colInfo.sql_type) ent.Columns.push(colInfo);
})
})
case "varchar":
colInfo.ts_type = "string";
colInfo.sql_type = "varchar";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "nvarchar":
colInfo.ts_type = "string";
colInfo.sql_type = "nvarchar";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "money":
colInfo.ts_type = "number";
colInfo.sql_type = "decimal";
break;
case "real":
colInfo.ts_type = "number";
colInfo.sql_type = "double";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "double":
colInfo.ts_type = "number";
colInfo.sql_type = "double";
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "decimal":
colInfo.ts_type = "number";
colInfo.sql_type = "decimal";
colInfo.numericPrecision = resp.NUMERIC_PRECISION;
colInfo.numericScale = resp.NUMERIC_SCALE;
colInfo.char_max_lenght =
resp.CHARACTER_MAXIMUM_LENGTH > 0
? resp.CHARACTER_MAXIMUM_LENGTH
: null;
break;
case "xml":
colInfo.ts_type = "string";
colInfo.sql_type = "text";
break;
case "json":
colInfo.ts_type = "Object";
colInfo.sql_type = "json";
break;
case "enum":
colInfo.ts_type = "string";
colInfo.sql_type = "enum";
colInfo.enumOptions = resp.column_type
.substring(5, resp.column_type.length - 1)
.replace(/\'/gi, '"');
break;
default:
TomgUtils.LogFatalError(
"Unknown column type:" + resp.DATA_TYPE
);
break;
}
if (colInfo.sql_type) ent.Columns.push(colInfo);
});
});
return entities;
}
async GetIndexesFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
async GetIndexesFromEntity(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let response = await this.ExecQuery<{
TableName: string, IndexName: string, ColumnName: string, is_unique: number,
is_primary_key: number//, is_descending_key: number//, is_included_column: number
TableName: string;
IndexName: string;
ColumnName: string;
is_unique: number;
is_primary_key: number; //, is_descending_key: number//, is_included_column: number
}>(`SELECT TABLE_NAME TableName,INDEX_NAME IndexName,COLUMN_NAME ColumnName,CASE WHEN NON_UNIQUE=0 THEN 1 ELSE 0 END is_unique,
CASE WHEN INDEX_NAME='PRIMARY' THEN 1 ELSE 0 END is_primary_key
FROM information_schema.statistics sta
WHERE table_schema like DATABASE();
`);
entities.forEach((ent) => {
response.filter((filterVal) => {
return filterVal.TableName == ent.EntityName;
}).forEach((resp) => {
let indexInfo: IndexInfo = <IndexInfo>{};
let indexColumnInfo: IndexColumnInfo = <IndexColumnInfo>{};
if (ent.Indexes.filter((filterVal) => {
return filterVal.name == resp.IndexName
}).length > 0) {
indexInfo = ent.Indexes.filter((filterVal) => {
return filterVal.name == resp.IndexName
})[0];
} else {
indexInfo.columns = <IndexColumnInfo[]>[];
indexInfo.name = resp.IndexName;
indexInfo.isUnique = resp.is_unique == 1 ? true : false;
indexInfo.isPrimaryKey = resp.is_primary_key == 1 ? true : false;
ent.Indexes.push(indexInfo);
}
indexColumnInfo.name = resp.ColumnName;
// indexColumnInfo.isIncludedColumn = resp.is_included_column == 1 ? true : false;
// indexColumnInfo.isDescending = resp.is_descending_key == 1 ? true : false;
indexInfo.columns.push(indexColumnInfo);
})
})
entities.forEach(ent => {
response
.filter(filterVal => {
return filterVal.TableName == ent.EntityName;
})
.forEach(resp => {
let indexInfo: IndexInfo = <IndexInfo>{};
let indexColumnInfo: IndexColumnInfo = <IndexColumnInfo>{};
if (
ent.Indexes.filter(filterVal => {
return filterVal.name == resp.IndexName;
}).length > 0
) {
indexInfo = ent.Indexes.filter(filterVal => {
return filterVal.name == resp.IndexName;
})[0];
} else {
indexInfo.columns = <IndexColumnInfo[]>[];
indexInfo.name = resp.IndexName;
indexInfo.isUnique = resp.is_unique == 1 ? true : false;
indexInfo.isPrimaryKey =
resp.is_primary_key == 1 ? true : false;
ent.Indexes.push(indexInfo);
}
indexColumnInfo.name = resp.ColumnName;
// indexColumnInfo.isIncludedColumn = resp.is_included_column == 1 ? true : false;
// indexColumnInfo.isDescending = resp.is_descending_key == 1 ? true : false;
indexInfo.columns.push(indexColumnInfo);
});
});
return entities;
}
async GetRelations(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
async GetRelations(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let response = await this.ExecQuery<{
TableWithForeignKey: string, FK_PartNo: number, ForeignKeyColumn: string,
TableReferenced: string, ForeignKeyColumnReferenced: string,
onDelete: "RESTRICT" | "CASCADE" | "SET NULL",
onUpdate: "RESTRICT" | "CASCADE" | "SET NULL", object_id: string
TableWithForeignKey: string;
FK_PartNo: number;
ForeignKeyColumn: string;
TableReferenced: string;
ForeignKeyColumnReferenced: string;
onDelete: "RESTRICT" | "CASCADE" | "SET NULL";
onUpdate: "RESTRICT" | "CASCADE" | "SET NULL";
object_id: string;
}>(`SELECT
CU.TABLE_NAME TableWithForeignKey,
CU.ORDINAL_POSITION FK_PartNo,
@ -272,10 +343,10 @@ export class MysqlDriver extends AbstractDriver {
AND CU.REFERENCED_TABLE_NAME IS NOT NULL;
`);
let relationsTemp: RelationTempInfo[] = <RelationTempInfo[]>[];
response.forEach((resp) => {
let rels = relationsTemp.find((val) => {
response.forEach(resp => {
let rels = relationsTemp.find(val => {
return val.object_id == resp.object_id;
})
});
if (rels == undefined) {
rels = <RelationTempInfo>{};
rels.ownerColumnsNames = [];
@ -289,129 +360,165 @@ export class MysqlDriver extends AbstractDriver {
}
rels.ownerColumnsNames.push(resp.ForeignKeyColumn);
rels.referencedColumnsNames.push(resp.ForeignKeyColumnReferenced);
})
relationsTemp.forEach((relationTmp) => {
let ownerEntity = entities.find((entitity) => {
});
relationsTemp.forEach(relationTmp => {
let ownerEntity = entities.find(entitity => {
return entitity.EntityName == relationTmp.ownerTable;
})
});
if (!ownerEntity) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity model ${relationTmp.ownerTable}.`
);
return;
}
let referencedEntity = entities.find((entitity) => {
let referencedEntity = entities.find(entitity => {
return entitity.EntityName == relationTmp.referencedTable;
})
});
if (!referencedEntity) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity model ${relationTmp.referencedTable}.`
);
return;
}
let ownerColumn = ownerEntity.Columns.find((column) => {
let ownerColumn = ownerEntity.Columns.find(column => {
return column.name == relationTmp.ownerColumnsNames[0];
})
});
if (!ownerColumn) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity column ${
relationTmp.ownerTable
}.${ownerColumn}.`
);
return;
}
let relatedColumn = referencedEntity.Columns.find((column) => {
let relatedColumn = referencedEntity.Columns.find(column => {
return column.name == relationTmp.referencedColumnsNames[0];
})
});
if (!relatedColumn) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity column ${
relationTmp.referencedTable
}.${relatedColumn}.`
);
return;
}
let ownColumn: ColumnInfo = ownerColumn;
let isOneToMany: boolean;
isOneToMany = false;
let index = ownerEntity.Indexes.find(
(index) => {
return index.isUnique && index.columns.some(col => {
return col.name == ownerColumn!.name
let index = ownerEntity.Indexes.find(index => {
return (
index.isUnique &&
index.columns.some(col => {
return col.name == ownerColumn!.name;
})
}
)
);
});
if (!index) {
isOneToMany = true;
} else {
isOneToMany = false;
}
let ownerRelation = new RelationInfo()
let columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '')
if (referencedEntity.Columns.filter((filterVal) => {
return filterVal.name == columnName;
}).length > 0) {
let ownerRelation = new RelationInfo();
let columnName =
ownerEntity.EntityName.toLowerCase() + (isOneToMany ? "s" : "");
if (
referencedEntity.Columns.filter(filterVal => {
return filterVal.name == columnName;
}).length > 0
) {
for (let i = 2; i <= ownerEntity.Columns.length; i++) {
columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '') + i.toString();
if (referencedEntity.Columns.filter((filterVal) => {
return filterVal.name == columnName;
}).length == 0) break;
columnName =
ownerEntity.EntityName.toLowerCase() +
(isOneToMany ? "s" : "") +
i.toString();
if (
referencedEntity.Columns.filter(filterVal => {
return filterVal.name == columnName;
}).length == 0
)
break;
}
}
ownerRelation.actionOnDelete = relationTmp.actionOnDelete
ownerRelation.actionOnUpdate = relationTmp.actionOnUpdate
ownerRelation.isOwner = true
ownerRelation.relatedColumn = relatedColumn.name.toLowerCase()
ownerRelation.relatedTable = relationTmp.referencedTable
ownerRelation.ownerTable = relationTmp.ownerTable
ownerRelation.ownerColumn = columnName
ownerRelation.relationType = isOneToMany ? "ManyToOne" : "OneToOne"
ownerColumn.relations.push(ownerRelation)
ownerRelation.actionOnDelete = relationTmp.actionOnDelete;
ownerRelation.actionOnUpdate = relationTmp.actionOnUpdate;
ownerRelation.isOwner = true;
ownerRelation.relatedColumn = relatedColumn.name.toLowerCase();
ownerRelation.relatedTable = relationTmp.referencedTable;
ownerRelation.ownerTable = relationTmp.ownerTable;
ownerRelation.ownerColumn = columnName;
ownerRelation.relationType = isOneToMany ? "ManyToOne" : "OneToOne";
ownerColumn.relations.push(ownerRelation);
if (isOneToMany) {
let col = new ColumnInfo()
col.name = columnName
let col = new ColumnInfo();
col.name = columnName;
let referencedRelation = new RelationInfo();
col.relations.push(referencedRelation)
referencedRelation.actionOnDelete = relationTmp.actionOnDelete
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate
referencedRelation.isOwner = false
referencedRelation.relatedColumn = ownerColumn.name
referencedRelation.relatedTable = relationTmp.ownerTable
referencedRelation.ownerTable = relationTmp.referencedTable
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase()
referencedRelation.relationType = "OneToMany"
referencedEntity.Columns.push(col)
col.relations.push(referencedRelation);
referencedRelation.actionOnDelete = relationTmp.actionOnDelete;
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate;
referencedRelation.isOwner = false;
referencedRelation.relatedColumn = ownerColumn.name;
referencedRelation.relatedTable = relationTmp.ownerTable;
referencedRelation.ownerTable = relationTmp.referencedTable;
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase();
referencedRelation.relationType = "OneToMany";
referencedEntity.Columns.push(col);
} else {
let col = new ColumnInfo()
col.name = columnName
let col = new ColumnInfo();
col.name = columnName;
let referencedRelation = new RelationInfo();
col.relations.push(referencedRelation)
referencedRelation.actionOnDelete = relationTmp.actionOnDelete
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate
referencedRelation.isOwner = false
referencedRelation.relatedColumn = ownerColumn.name
referencedRelation.relatedTable = relationTmp.ownerTable
referencedRelation.ownerTable = relationTmp.referencedTable
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase()
referencedRelation.relationType = "OneToOne"
col.relations.push(referencedRelation);
referencedRelation.actionOnDelete = relationTmp.actionOnDelete;
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate;
referencedRelation.isOwner = false;
referencedRelation.relatedColumn = ownerColumn.name;
referencedRelation.relatedTable = relationTmp.ownerTable;
referencedRelation.ownerTable = relationTmp.referencedTable;
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase();
referencedRelation.relationType = "OneToOne";
referencedEntity.Columns.push(col)
referencedEntity.Columns.push(col);
}
})
});
return entities;
}
async DisconnectFromServer() {
let promise = new Promise<boolean>(
(resolve, reject) => {
this.Connection.end((err) => {
if (!err) {
//Connection successfull
resolve(true)
}
else {
TomgUtils.LogFatalError(`Error disconnecting to ${this.EngineName} Server.`, false, err.message)
reject(err)
}
});
}
)
if (this.Connection)
await promise;
let promise = new Promise<boolean>((resolve, reject) => {
this.Connection.end(err => {
if (!err) {
//Connection successfull
resolve(true);
} else {
TomgUtils.LogFatalError(
`Error disconnecting to ${this.EngineName} Server.`,
false,
err.message
);
reject(err);
}
});
});
if (this.Connection) await promise;
}
private Connection: MYSQL.Connection;
async ConnectToServer(database: string, server: string, port: number, user: string, password: string, ssl: boolean) {
let config: MYSQL.ConnectionConfig
async ConnectToServer(
database: string,
server: string,
port: number,
user: string,
password: string,
ssl: boolean
) {
let config: MYSQL.ConnectionConfig;
if (ssl) {
config = {
database: database,
@ -422,7 +529,7 @@ export class MysqlDriver extends AbstractDriver {
ssl: {
rejectUnauthorized: false
}
}
};
} else {
config = {
database: database,
@ -430,55 +537,55 @@ export class MysqlDriver extends AbstractDriver {
port: port,
user: user,
password: password
}
};
}
let promise = new Promise<boolean>((resolve, reject) => {
this.Connection = MYSQL.createConnection(config);
let promise = new Promise<boolean>(
(resolve, reject) => {
this.Connection = MYSQL.createConnection(config)
this.Connection.connect((err) => {
if (!err) {
//Connection successfull
resolve(true)
}
else {
TomgUtils.LogFatalError(`Error connecting to ${this.EngineName} Server.`, false, err.message)
reject(err)
}
});
}
)
this.Connection.connect(err => {
if (!err) {
//Connection successfull
resolve(true);
} else {
TomgUtils.LogFatalError(
`Error connecting to ${this.EngineName} Server.`,
false,
err.message
);
reject(err);
}
});
});
await promise;
}
async CreateDB(dbName: string) {
let resp = await this.ExecQuery<any>(`CREATE DATABASE ${dbName}; `)
let resp = await this.ExecQuery<any>(`CREATE DATABASE ${dbName}; `);
}
async UseDB(dbName: string) {
let resp = await this.ExecQuery<any>(`USE ${dbName}; `)
let resp = await this.ExecQuery<any>(`USE ${dbName}; `);
}
async DropDB(dbName: string) {
let resp = await this.ExecQuery<any>(`DROP DATABASE ${dbName}; `)
let resp = await this.ExecQuery<any>(`DROP DATABASE ${dbName}; `);
}
async CheckIfDBExists(dbName: string): Promise<boolean> {
let resp = await this.ExecQuery<any>(`SHOW DATABASES LIKE '${dbName}' `)
let resp = await this.ExecQuery<any>(
`SHOW DATABASES LIKE '${dbName}' `
);
return resp.length > 0;
}
async ExecQuery<T>(sql: string): Promise<Array<T>> {
let ret: Array<T> = [];
let that = this;
let query = this.Connection.query(sql)
let query = this.Connection.query(sql);
let stream = query.stream({});
let promise = new Promise<boolean>(
(resolve, reject) => {
stream.on('data',
chunk => {
ret.push(<T><any>chunk)
});
stream.on('end', () => resolve(true));
})
let promise = new Promise<boolean>((resolve, reject) => {
stream.on("data", chunk => {
ret.push(<T>(<any>chunk));
});
stream.on("end", () => resolve(true));
});
await promise;
return ret;
}

View File

@ -1,12 +1,11 @@
import { AbstractDriver } from './AbstractDriver'
import { ColumnInfo } from './../models/ColumnInfo'
import { EntityInfo } from './../models/EntityInfo'
import { RelationInfo } from './../models/RelationInfo'
import { DatabaseModel } from './../models/DatabaseModel'
import { promisify } from 'util'
import { request } from 'https';
import * as TomgUtils from './../Utils'
import { AbstractDriver } from "./AbstractDriver";
import { ColumnInfo } from "./../models/ColumnInfo";
import { EntityInfo } from "./../models/EntityInfo";
import { RelationInfo } from "./../models/RelationInfo";
import { DatabaseModel } from "./../models/DatabaseModel";
import { promisify } from "util";
import { request } from "https";
import * as TomgUtils from "./../Utils";
/**
* OracleDriver
@ -16,117 +15,142 @@ export class OracleDriver extends AbstractDriver {
constructor() {
super();
try {
this.Oracle = require('oracledb')
this.Oracle = require("oracledb");
} catch (error) {
TomgUtils.LogFatalError('', false, error);
TomgUtils.LogFatalError("", false, error);
throw error;
}
}
FindPrimaryColumnsFromIndexes(dbModel: DatabaseModel) {
dbModel.entities.forEach(entity => {
let primaryIndex = entity.Indexes.find(v => v.isPrimaryKey);
if (!primaryIndex) {
TomgUtils.LogFatalError(`Table ${entity.EntityName} has no PK.`, false)
TomgUtils.LogFatalError(
`Table ${entity.EntityName} has no PK.`,
false
);
return;
}
entity.Columns.forEach(col => {
if (primaryIndex!.columns.some(cIndex => cIndex.name == col.name)) col.isPrimary = true
})
if (
primaryIndex!.columns.some(
cIndex => cIndex.name == col.name
)
)
col.isPrimary = true;
});
});
}
async GetAllTables(schema: string): Promise<EntityInfo[]> {
let response: any[][] = (await this.Connection.execute(` SELECT TABLE_NAME FROM all_tables WHERE owner = (select user from dual)`)).rows!;
let response: any[][] = (await this.Connection.execute(
` SELECT TABLE_NAME FROM all_tables WHERE owner = (select user from dual)`
)).rows!;
let ret: EntityInfo[] = <EntityInfo[]>[];
response.forEach((val) => {
response.forEach(val => {
let ent: EntityInfo = new EntityInfo();
ent.EntityName = val[0];
ent.Columns = <ColumnInfo[]>[];
ent.Indexes = <IndexInfo[]>[];
ret.push(ent);
})
});
return ret;
}
async GetCoulmnsFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
let response: any[][] = (await this.Connection.execute(`SELECT TABLE_NAME, COLUMN_NAME, DATA_DEFAULT, NULLABLE, DATA_TYPE, DATA_LENGTH,
async GetCoulmnsFromEntity(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let response: any[][] = (await this.Connection
.execute(`SELECT TABLE_NAME, COLUMN_NAME, DATA_DEFAULT, NULLABLE, DATA_TYPE, DATA_LENGTH,
DATA_PRECISION, DATA_SCALE, IDENTITY_COLUMN
FROM USER_TAB_COLUMNS`)).rows!;
entities.forEach((ent) => {
response.filter((filterVal) => {
return filterVal[0] == ent.EntityName;
}).forEach((resp) => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.name = resp[1];
colInfo.is_nullable = resp[3] == 'Y' ? true : false;
colInfo.is_generated = resp[8] == 'YES' ? true : false;
colInfo.default = resp[2];
switch (resp[4].toLowerCase()) {
case "number":
colInfo.ts_type = "number"
colInfo.sql_type = "int"
colInfo.char_max_lenght = resp[5] > 0 ? resp[5] : null;
break;
case "varchar2":
colInfo.ts_type = "number"
colInfo.sql_type = "smallint"
colInfo.char_max_lenght = resp[5] > 0 ? resp[5] : null;
break;
default:
TomgUtils.LogFatalError("Unknown column type:" + resp[4]);
break;
}
entities.forEach(ent => {
response
.filter(filterVal => {
return filterVal[0] == ent.EntityName;
})
.forEach(resp => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.name = resp[1];
colInfo.is_nullable = resp[3] == "Y" ? true : false;
colInfo.is_generated = resp[8] == "YES" ? true : false;
colInfo.default = resp[2];
switch (resp[4].toLowerCase()) {
case "number":
colInfo.ts_type = "number";
colInfo.sql_type = "int";
colInfo.char_max_lenght =
resp[5] > 0 ? resp[5] : null;
break;
case "varchar2":
colInfo.ts_type = "number";
colInfo.sql_type = "smallint";
colInfo.char_max_lenght =
resp[5] > 0 ? resp[5] : null;
break;
default:
TomgUtils.LogFatalError(
"Unknown column type:" + resp[4]
);
break;
}
if (colInfo.sql_type) ent.Columns.push(colInfo);
})
})
if (colInfo.sql_type) ent.Columns.push(colInfo);
});
});
return entities;
}
async GetIndexesFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
let response: any[][] = (await this.Connection.execute(`SELECT ind.TABLE_NAME, ind.INDEX_NAME, col.COLUMN_NAME,ind.UNIQUENESS, CASE WHEN uc.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END
async GetIndexesFromEntity(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let response: any[][] = (await this.Connection
.execute(`SELECT ind.TABLE_NAME, ind.INDEX_NAME, col.COLUMN_NAME,ind.UNIQUENESS, CASE WHEN uc.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END
FROM USER_INDEXES ind
JOIN USER_IND_COLUMNS col ON ind.INDEX_NAME=col.INDEX_NAME
LEFT JOIN USER_CONSTRAINTS uc ON uc.INDEX_NAME = ind.INDEX_NAME
ORDER BY col.INDEX_NAME ASC ,col.COLUMN_POSITION ASC`)).rows!;
entities.forEach((ent) => {
response.filter((filterVal) => {
return filterVal[0] == ent.EntityName;
}).forEach((resp) => {
let indexInfo: IndexInfo = <IndexInfo>{};
let indexColumnInfo: IndexColumnInfo = <IndexColumnInfo>{};
if (ent.Indexes.filter((filterVal) => {
return filterVal.name == resp[1]
}).length > 0) {
indexInfo = ent.Indexes.filter((filterVal) => {
return filterVal.name == resp[1]
})[0];
} else {
indexInfo.columns = <IndexColumnInfo[]>[];
indexInfo.name = resp[1];
indexInfo.isUnique = resp[3] == 'UNIQUE' ? true : false;
indexInfo.isPrimaryKey = resp[4] == 1 ? true : false;
ent.Indexes.push(indexInfo);
}
indexColumnInfo.name = resp[2];
// indexColumnInfo.isIncludedColumn = resp.is_included_column == 1 ? true : false;
// indexColumnInfo.isDescending = resp.is_descending_key == 1 ? true : false;
indexInfo.columns.push(indexColumnInfo);
})
})
entities.forEach(ent => {
response
.filter(filterVal => {
return filterVal[0] == ent.EntityName;
})
.forEach(resp => {
let indexInfo: IndexInfo = <IndexInfo>{};
let indexColumnInfo: IndexColumnInfo = <IndexColumnInfo>{};
if (
ent.Indexes.filter(filterVal => {
return filterVal.name == resp[1];
}).length > 0
) {
indexInfo = ent.Indexes.filter(filterVal => {
return filterVal.name == resp[1];
})[0];
} else {
indexInfo.columns = <IndexColumnInfo[]>[];
indexInfo.name = resp[1];
indexInfo.isUnique = resp[3] == "UNIQUE" ? true : false;
indexInfo.isPrimaryKey = resp[4] == 1 ? true : false;
ent.Indexes.push(indexInfo);
}
indexColumnInfo.name = resp[2];
// indexColumnInfo.isIncludedColumn = resp.is_included_column == 1 ? true : false;
// indexColumnInfo.isDescending = resp.is_descending_key == 1 ? true : false;
indexInfo.columns.push(indexColumnInfo);
});
});
return entities;
}
async GetRelations(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
let response: any[][] = (await this.Connection.execute(`select owner.TABLE_NAME ownTbl,ownCol.POSITION,ownCol.COLUMN_NAME,
async GetRelations(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let response: any[][] = (await this.Connection
.execute(`select owner.TABLE_NAME ownTbl,ownCol.POSITION,ownCol.COLUMN_NAME,
child.TABLE_NAME,childCol.COLUMN_NAME,
owner.DELETE_RULE,
4,owner.CONSTRAINT_NAME
@ -134,14 +158,14 @@ export class OracleDriver extends AbstractDriver {
join user_constraints child on owner.r_constraint_name=child.CONSTRAINT_NAME and child.constraint_type in ('P','U')
JOIN USER_CONS_COLUMNS ownCol ON owner.CONSTRAINT_NAME = ownCol.CONSTRAINT_NAME
JOIN USER_CONS_COLUMNS childCol ON child.CONSTRAINT_NAME = childCol.CONSTRAINT_NAME AND ownCol.POSITION=childCol.POSITION
ORDER BY ownTbl ASC, owner.CONSTRAINT_NAME ASC, ownCol.POSITION ASC`)).rows!;
ORDER BY ownTbl ASC, owner.CONSTRAINT_NAME ASC, ownCol.POSITION ASC`))
.rows!;
let relationsTemp: RelationTempInfo[] = <RelationTempInfo[]>[];
response.forEach((resp) => {
let rels = relationsTemp.find((val) => {
response.forEach(resp => {
let rels = relationsTemp.find(val => {
return val.object_id == resp[6];
})
});
if (rels == undefined) {
rels = <RelationTempInfo>{};
rels.ownerColumnsNames = [];
@ -155,151 +179,180 @@ export class OracleDriver extends AbstractDriver {
}
rels.ownerColumnsNames.push(resp[2]);
rels.referencedColumnsNames.push(resp[4]);
})
relationsTemp.forEach((relationTmp) => {
let ownerEntity = entities.find((entitity) => {
});
relationsTemp.forEach(relationTmp => {
let ownerEntity = entities.find(entitity => {
return entitity.EntityName == relationTmp.ownerTable;
})
});
if (!ownerEntity) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity model ${relationTmp.ownerTable}.`
);
return;
}
let referencedEntity = entities.find((entitity) => {
let referencedEntity = entities.find(entitity => {
return entitity.EntityName == relationTmp.referencedTable;
})
});
if (!referencedEntity) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity model ${relationTmp.referencedTable}.`
);
return;
}
let ownerColumn = ownerEntity.Columns.find((column) => {
let ownerColumn = ownerEntity.Columns.find(column => {
return column.name == relationTmp.ownerColumnsNames[0];
})
});
if (!ownerColumn) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity column ${
relationTmp.ownerTable
}.${ownerColumn}.`
);
return;
}
let relatedColumn = referencedEntity.Columns.find((column) => {
let relatedColumn = referencedEntity.Columns.find(column => {
return column.name == relationTmp.referencedColumnsNames[0];
})
});
if (!relatedColumn) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity column ${
relationTmp.referencedTable
}.${relatedColumn}.`
);
return;
}
let ownColumn: ColumnInfo = ownerColumn;
let isOneToMany: boolean;
isOneToMany = false;
let index = ownerEntity.Indexes.find(
(index) => {
return index.isUnique && index.columns.some(col => {
return col.name == ownerColumn!.name
let index = ownerEntity.Indexes.find(index => {
return (
index.isUnique &&
index.columns.some(col => {
return col.name == ownerColumn!.name;
})
}
)
);
});
if (!index) {
isOneToMany = true;
} else {
isOneToMany = false;
}
let ownerRelation = new RelationInfo()
let columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '')
if (referencedEntity.Columns.filter((filterVal) => {
return filterVal.name == columnName;
}).length > 0) {
let ownerRelation = new RelationInfo();
let columnName =
ownerEntity.EntityName.toLowerCase() + (isOneToMany ? "s" : "");
if (
referencedEntity.Columns.filter(filterVal => {
return filterVal.name == columnName;
}).length > 0
) {
for (let i = 2; i <= ownerEntity.Columns.length; i++) {
columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '') + i.toString();
if (referencedEntity.Columns.filter((filterVal) => {
return filterVal.name == columnName;
}).length == 0) break;
columnName =
ownerEntity.EntityName.toLowerCase() +
(isOneToMany ? "s" : "") +
i.toString();
if (
referencedEntity.Columns.filter(filterVal => {
return filterVal.name == columnName;
}).length == 0
)
break;
}
}
ownerRelation.actionOnDelete = relationTmp.actionOnDelete
ownerRelation.actionOnUpdate = relationTmp.actionOnUpdate
ownerRelation.isOwner = true
ownerRelation.relatedColumn = relatedColumn.name.toLowerCase()
ownerRelation.relatedTable = relationTmp.referencedTable
ownerRelation.ownerTable = relationTmp.ownerTable
ownerRelation.ownerColumn = columnName
ownerRelation.relationType = isOneToMany ? "ManyToOne" : "OneToOne"
ownerColumn.relations.push(ownerRelation)
ownerRelation.actionOnDelete = relationTmp.actionOnDelete;
ownerRelation.actionOnUpdate = relationTmp.actionOnUpdate;
ownerRelation.isOwner = true;
ownerRelation.relatedColumn = relatedColumn.name.toLowerCase();
ownerRelation.relatedTable = relationTmp.referencedTable;
ownerRelation.ownerTable = relationTmp.ownerTable;
ownerRelation.ownerColumn = columnName;
ownerRelation.relationType = isOneToMany ? "ManyToOne" : "OneToOne";
ownerColumn.relations.push(ownerRelation);
if (isOneToMany) {
let col = new ColumnInfo()
col.name = columnName
let col = new ColumnInfo();
col.name = columnName;
let referencedRelation = new RelationInfo();
col.relations.push(referencedRelation)
referencedRelation.actionOnDelete = relationTmp.actionOnDelete
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate
referencedRelation.isOwner = false
referencedRelation.relatedColumn = ownerColumn.name
referencedRelation.relatedTable = relationTmp.ownerTable
referencedRelation.ownerTable = relationTmp.referencedTable
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase()
referencedRelation.relationType = "OneToMany"
referencedEntity.Columns.push(col)
col.relations.push(referencedRelation);
referencedRelation.actionOnDelete = relationTmp.actionOnDelete;
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate;
referencedRelation.isOwner = false;
referencedRelation.relatedColumn = ownerColumn.name;
referencedRelation.relatedTable = relationTmp.ownerTable;
referencedRelation.ownerTable = relationTmp.referencedTable;
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase();
referencedRelation.relationType = "OneToMany";
referencedEntity.Columns.push(col);
} else {
let col = new ColumnInfo()
col.name = columnName
let col = new ColumnInfo();
col.name = columnName;
let referencedRelation = new RelationInfo();
col.relations.push(referencedRelation)
referencedRelation.actionOnDelete = relationTmp.actionOnDelete
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate
referencedRelation.isOwner = false
referencedRelation.relatedColumn = ownerColumn.name
referencedRelation.relatedTable = relationTmp.ownerTable
referencedRelation.ownerTable = relationTmp.referencedTable
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase()
referencedRelation.relationType = "OneToOne"
col.relations.push(referencedRelation);
referencedRelation.actionOnDelete = relationTmp.actionOnDelete;
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate;
referencedRelation.isOwner = false;
referencedRelation.relatedColumn = ownerColumn.name;
referencedRelation.relatedTable = relationTmp.ownerTable;
referencedRelation.ownerTable = relationTmp.referencedTable;
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase();
referencedRelation.relationType = "OneToOne";
referencedEntity.Columns.push(col)
referencedEntity.Columns.push(col);
}
})
});
return entities;
}
async DisconnectFromServer() {
if (this.Connection)
await this.Connection.close();
if (this.Connection) await this.Connection.close();
}
private Connection: any/*Oracle.IConnection*/;
async ConnectToServer(database: string, server: string, port: number, user: string, password: string, ssl: boolean) {
let config: any/*Oracle.IConnectionAttributes*/ = {
private Connection: any /*Oracle.IConnection*/;
async ConnectToServer(
database: string,
server: string,
port: number,
user: string,
password: string,
ssl: boolean
) {
let config: any /*Oracle.IConnectionAttributes*/ = {
user: user,
password: password,
// connectString: `${server}:${port}/ORCLCDB.localdomain/${database}`,
connectString: `${server}:${port}/${database}`,
externalAuth: ssl
}
};
let that = this;
let promise = new Promise<boolean>(
(resolve, reject) => {
this.Oracle.getConnection(
config,
function (err, connection) {
if (!err) {
//Connection successfull
that.Connection = connection
resolve(true)
}
else {
TomgUtils.LogFatalError('Error connecting to Oracle Server.', false, err.message)
reject(err)
}
});
}
)
let promise = new Promise<boolean>((resolve, reject) => {
this.Oracle.getConnection(config, function(err, connection) {
if (!err) {
//Connection successfull
that.Connection = connection;
resolve(true);
} else {
TomgUtils.LogFatalError(
"Error connecting to Oracle Server.",
false,
err.message
);
reject(err);
}
});
});
await promise;
}
async CreateDB(dbName: string) {
}
async UseDB(dbName: string) {
}
async DropDB(dbName: string) {
}
async CreateDB(dbName: string) {}
async UseDB(dbName: string) {}
async DropDB(dbName: string) {}
async CheckIfDBExists(dbName: string): Promise<boolean> {
return true;
}

View File

@ -1,10 +1,10 @@
import { AbstractDriver } from './AbstractDriver'
import * as PG from 'pg'
import { ColumnInfo } from './../models/ColumnInfo'
import { EntityInfo } from './../models/EntityInfo'
import { RelationInfo } from './../models/RelationInfo'
import { DatabaseModel } from './../models/DatabaseModel'
import * as TomgUtils from './../Utils'
import { AbstractDriver } from "./AbstractDriver";
import * as PG from "pg";
import { ColumnInfo } from "./../models/ColumnInfo";
import { EntityInfo } from "./../models/EntityInfo";
import { RelationInfo } from "./../models/RelationInfo";
import { DatabaseModel } from "./../models/DatabaseModel";
import * as TomgUtils from "./../Utils";
/**
* PostgresDriver
*/
@ -15,215 +15,255 @@ export class PostgresDriver extends AbstractDriver {
dbModel.entities.forEach(entity => {
let primaryIndex = entity.Indexes.find(v => v.isPrimaryKey);
if (!primaryIndex) {
TomgUtils.LogFatalError(`Table ${entity.EntityName} has no PK.`, false)
TomgUtils.LogFatalError(
`Table ${entity.EntityName} has no PK.`,
false
);
return;
}
entity.Columns.forEach(col => {
if (primaryIndex!.columns.some(cIndex => cIndex.name == col.name)) col.isPrimary = true
})
if (
primaryIndex!.columns.some(
cIndex => cIndex.name == col.name
)
)
col.isPrimary = true;
});
});
}
async GetAllTables(schema: string): Promise<EntityInfo[]> {
let response: { table_schema: string, table_name: string }[]
= (await this.Connection.query(`SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND table_schema = '${schema}' `)).rows;
let response: {
table_schema: string;
table_name: string;
}[] = (await this.Connection.query(
`SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND table_schema = '${schema}' `
)).rows;
let ret: EntityInfo[] = <EntityInfo[]>[];
response.forEach((val) => {
response.forEach(val => {
let ent: EntityInfo = new EntityInfo();
ent.EntityName = val.table_name;
ent.Columns = <ColumnInfo[]>[];
ent.Indexes = <IndexInfo[]>[];
ret.push(ent);
})
});
return ret;
}
async GetCoulmnsFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
async GetCoulmnsFromEntity(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let response: {
table_name: string, column_name: string, column_default: string,
is_nullable: string, data_type: string, character_maximum_length: number,
numeric_precision: number, numeric_scale: number, isidentity: string
}[]
= (await this.Connection.query(`SELECT table_name,column_name,column_default,is_nullable,
table_name: string;
column_name: string;
column_default: string;
is_nullable: string;
data_type: string;
character_maximum_length: number;
numeric_precision: number;
numeric_scale: number;
isidentity: string;
}[] = (await this.Connection
.query(`SELECT table_name,column_name,column_default,is_nullable,
data_type,character_maximum_length,numeric_precision,numeric_scale
--,COLUMNPROPERTY(object_id(table_name), column_name, 'isidentity') isidentity
, case when column_default LIKE 'nextval%' then 'YES' else 'NO' end isidentity
FROM INFORMATION_SCHEMA.COLUMNS where table_schema ='${schema}'`)).rows;
entities.forEach((ent) => {
response.filter((filterVal) => {
return filterVal.table_name == ent.EntityName;
}).forEach((resp) => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.name = resp.column_name;
colInfo.is_nullable = resp.is_nullable == 'YES' ? true : false;
colInfo.is_generated = resp.isidentity == 'YES' ? true : false;
colInfo.default = colInfo.is_generated ? '' : resp.column_default;
switch (resp.data_type) {
case "integer":
colInfo.ts_type = "number"
colInfo.sql_type = "int"
break;
case "character varying":
colInfo.ts_type = "string"
colInfo.sql_type = "varchar"
colInfo.char_max_lenght = resp.character_maximum_length > 0 ? resp.character_maximum_length : null;
break;
case "text":
colInfo.ts_type = "string"
colInfo.sql_type = "text"
break;
case "uuid":
colInfo.ts_type = "string"
colInfo.sql_type = "uuid"
break;
case "smallint":
colInfo.ts_type = "number"
colInfo.sql_type = "smallint"
break;
case "bigint":
colInfo.ts_type = "string"
colInfo.sql_type = "bigint"
break;
case "date":
colInfo.ts_type = "string"
colInfo.sql_type = "date"
break;
case "boolean":
colInfo.ts_type = "boolean"
colInfo.sql_type = "boolean"
break;
case "double precision":
colInfo.ts_type = "number"
colInfo.sql_type = "double"
colInfo.numericPrecision = resp.numeric_precision
colInfo.numericScale = resp.numeric_scale
break;
case "real":
colInfo.ts_type = "number"
colInfo.sql_type = "float"
colInfo.numericPrecision = resp.numeric_precision
colInfo.numericScale = resp.numeric_scale
break;
case "numeric":
colInfo.ts_type = "string"
colInfo.sql_type = "numeric"
colInfo.numericPrecision = resp.numeric_precision
colInfo.numericScale = resp.numeric_scale
break;
case "time without time zone":
colInfo.ts_type = "string"
colInfo.sql_type = "time without time zone"
break;
case "timestamp without time zone":
colInfo.ts_type = "Date"
colInfo.sql_type = "timestamp"
break;
case "timestamp with time zone":
colInfo.ts_type = "Date"
colInfo.sql_type = "timestamp"
break;
case "timestamp with time zone":
colInfo.ts_type = "Date"
colInfo.sql_type = "timestamp"
break;
case "json":
colInfo.ts_type = "Object"
colInfo.sql_type = "json"
break;
case "jsonb":
colInfo.ts_type = "Object"
colInfo.sql_type = "jsonb"
break;
case "money":
colInfo.ts_type = "string"
colInfo.sql_type = "money"
break;
case "character":
colInfo.ts_type = "string"
colInfo.sql_type = "character"
colInfo.char_max_lenght = resp.character_maximum_length > 0 ? resp.character_maximum_length : null;
break;
case "bytea":
colInfo.ts_type = "Buffer"
colInfo.sql_type = "bytea"
break;
case "interval":
colInfo.ts_type = "any"
colInfo.sql_type = "interval"
break;
case "time with time zone":
colInfo.ts_type = "string"
colInfo.sql_type = "time with time zone"
break;
case "point":
colInfo.ts_type = "string | Object"
colInfo.sql_type = "point"
break;
case "line":
colInfo.ts_type = "string"
colInfo.sql_type = "line"
break;
case "lseg":
colInfo.ts_type = "string | string[]"
colInfo.sql_type = "lseg"
break;
case "box":
colInfo.ts_type = "string | Object"
colInfo.sql_type = "box"
break;
case "path":
colInfo.ts_type = "string"
colInfo.sql_type = "path"
break;
case "polygon":
colInfo.ts_type = "string"
colInfo.sql_type = "polygon"
break;
case "circle":
colInfo.ts_type = "string | Object"
colInfo.sql_type = "circle"
break;
case "cidr":
colInfo.ts_type = "string"
colInfo.sql_type = "cidr"
break;
case "inet":
colInfo.ts_type = "string"
colInfo.sql_type = "inet"
break;
case "macaddr":
colInfo.ts_type = "string"
colInfo.sql_type = "macaddr"
break;
case "bit":
colInfo.ts_type = "string"
colInfo.sql_type = "bit"
break;
case "bit varying":
colInfo.ts_type = "string"
colInfo.sql_type = "bit varying"
break;
case "xml":
colInfo.ts_type = "string"
colInfo.sql_type = "xml"
break;
default:
TomgUtils.LogFatalError("Unknown column type:" + resp.data_type);
break;
}
FROM INFORMATION_SCHEMA.COLUMNS where table_schema ='${schema}'`))
.rows;
entities.forEach(ent => {
response
.filter(filterVal => {
return filterVal.table_name == ent.EntityName;
})
.forEach(resp => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.name = resp.column_name;
colInfo.is_nullable =
resp.is_nullable == "YES" ? true : false;
colInfo.is_generated =
resp.isidentity == "YES" ? true : false;
colInfo.default = colInfo.is_generated
? ""
: resp.column_default;
switch (resp.data_type) {
case "integer":
colInfo.ts_type = "number";
colInfo.sql_type = "int";
break;
case "character varying":
colInfo.ts_type = "string";
colInfo.sql_type = "varchar";
colInfo.char_max_lenght =
resp.character_maximum_length > 0
? resp.character_maximum_length
: null;
break;
case "text":
colInfo.ts_type = "string";
colInfo.sql_type = "text";
break;
case "uuid":
colInfo.ts_type = "string";
colInfo.sql_type = "uuid";
break;
case "smallint":
colInfo.ts_type = "number";
colInfo.sql_type = "smallint";
break;
case "bigint":
colInfo.ts_type = "string";
colInfo.sql_type = "bigint";
break;
case "date":
colInfo.ts_type = "string";
colInfo.sql_type = "date";
break;
case "boolean":
colInfo.ts_type = "boolean";
colInfo.sql_type = "boolean";
break;
case "double precision":
colInfo.ts_type = "number";
colInfo.sql_type = "double";
colInfo.numericPrecision = resp.numeric_precision;
colInfo.numericScale = resp.numeric_scale;
break;
case "real":
colInfo.ts_type = "number";
colInfo.sql_type = "float";
colInfo.numericPrecision = resp.numeric_precision;
colInfo.numericScale = resp.numeric_scale;
break;
case "numeric":
colInfo.ts_type = "string";
colInfo.sql_type = "numeric";
colInfo.numericPrecision = resp.numeric_precision;
colInfo.numericScale = resp.numeric_scale;
break;
case "time without time zone":
colInfo.ts_type = "string";
colInfo.sql_type = "time without time zone";
break;
case "timestamp without time zone":
colInfo.ts_type = "Date";
colInfo.sql_type = "timestamp";
break;
case "timestamp with time zone":
colInfo.ts_type = "Date";
colInfo.sql_type = "timestamp";
break;
case "timestamp with time zone":
colInfo.ts_type = "Date";
colInfo.sql_type = "timestamp";
break;
case "json":
colInfo.ts_type = "Object";
colInfo.sql_type = "json";
break;
case "jsonb":
colInfo.ts_type = "Object";
colInfo.sql_type = "jsonb";
break;
case "money":
colInfo.ts_type = "string";
colInfo.sql_type = "money";
break;
case "character":
colInfo.ts_type = "string";
colInfo.sql_type = "character";
colInfo.char_max_lenght =
resp.character_maximum_length > 0
? resp.character_maximum_length
: null;
break;
case "bytea":
colInfo.ts_type = "Buffer";
colInfo.sql_type = "bytea";
break;
case "interval":
colInfo.ts_type = "any";
colInfo.sql_type = "interval";
break;
case "time with time zone":
colInfo.ts_type = "string";
colInfo.sql_type = "time with time zone";
break;
case "point":
colInfo.ts_type = "string | Object";
colInfo.sql_type = "point";
break;
case "line":
colInfo.ts_type = "string";
colInfo.sql_type = "line";
break;
case "lseg":
colInfo.ts_type = "string | string[]";
colInfo.sql_type = "lseg";
break;
case "box":
colInfo.ts_type = "string | Object";
colInfo.sql_type = "box";
break;
case "path":
colInfo.ts_type = "string";
colInfo.sql_type = "path";
break;
case "polygon":
colInfo.ts_type = "string";
colInfo.sql_type = "polygon";
break;
case "circle":
colInfo.ts_type = "string | Object";
colInfo.sql_type = "circle";
break;
case "cidr":
colInfo.ts_type = "string";
colInfo.sql_type = "cidr";
break;
case "inet":
colInfo.ts_type = "string";
colInfo.sql_type = "inet";
break;
case "macaddr":
colInfo.ts_type = "string";
colInfo.sql_type = "macaddr";
break;
case "bit":
colInfo.ts_type = "string";
colInfo.sql_type = "bit";
break;
case "bit varying":
colInfo.ts_type = "string";
colInfo.sql_type = "bit varying";
break;
case "xml":
colInfo.ts_type = "string";
colInfo.sql_type = "xml";
break;
default:
TomgUtils.LogFatalError(
"Unknown column type:" + resp.data_type
);
break;
}
if (colInfo.sql_type) ent.Columns.push(colInfo);
})
})
if (colInfo.sql_type) ent.Columns.push(colInfo);
});
});
return entities;
}
async GetIndexesFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
async GetIndexesFromEntity(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let response: {
tablename: string, indexname: string, columnname: string, is_unique: number,
is_primary_key: number//, is_descending_key: number//, is_included_column: number
}[]
= (await this.Connection.query(`SELECT
tablename: string;
indexname: string;
columnname: string;
is_unique: number;
is_primary_key: number; //, is_descending_key: number//, is_included_column: number
}[] = (await this.Connection.query(`SELECT
c.relname AS tablename,
i.relname as indexname,
f.attname AS columnname,
@ -251,46 +291,56 @@ export class PostgresDriver extends AbstractDriver {
AND f.attnum > 0
AND i.oid<>0
ORDER BY c.relname,f.attname;`)).rows;
entities.forEach((ent) => {
response.filter((filterVal) => {
return filterVal.tablename == ent.EntityName;
}).forEach((resp) => {
let indexInfo: IndexInfo = <IndexInfo>{};
let indexColumnInfo: IndexColumnInfo = <IndexColumnInfo>{};
if (ent.Indexes.filter((filterVal) => {
return filterVal.name == resp.indexname
}).length > 0) {
indexInfo = ent.Indexes.filter((filterVal) => {
return filterVal.name == resp.indexname
})[0];
} else {
indexInfo.columns = <IndexColumnInfo[]>[];
indexInfo.name = resp.indexname;
indexInfo.isUnique = resp.is_unique == 1 ? true : false;
indexInfo.isPrimaryKey = resp.is_primary_key == 1 ? true : false;
ent.Indexes.push(indexInfo);
}
indexColumnInfo.name = resp.columnname;
if (resp.is_primary_key == 0) {
indexInfo.isPrimaryKey = false;
}
// indexColumnInfo.isIncludedColumn = resp.is_included_column == 1 ? true : false;
//indexColumnInfo.isDescending = resp.is_descending_key == 1 ? true : false;
indexInfo.columns.push(indexColumnInfo);
})
})
entities.forEach(ent => {
response
.filter(filterVal => {
return filterVal.tablename == ent.EntityName;
})
.forEach(resp => {
let indexInfo: IndexInfo = <IndexInfo>{};
let indexColumnInfo: IndexColumnInfo = <IndexColumnInfo>{};
if (
ent.Indexes.filter(filterVal => {
return filterVal.name == resp.indexname;
}).length > 0
) {
indexInfo = ent.Indexes.filter(filterVal => {
return filterVal.name == resp.indexname;
})[0];
} else {
indexInfo.columns = <IndexColumnInfo[]>[];
indexInfo.name = resp.indexname;
indexInfo.isUnique = resp.is_unique == 1 ? true : false;
indexInfo.isPrimaryKey =
resp.is_primary_key == 1 ? true : false;
ent.Indexes.push(indexInfo);
}
indexColumnInfo.name = resp.columnname;
if (resp.is_primary_key == 0) {
indexInfo.isPrimaryKey = false;
}
// indexColumnInfo.isIncludedColumn = resp.is_included_column == 1 ? true : false;
//indexColumnInfo.isDescending = resp.is_descending_key == 1 ? true : false;
indexInfo.columns.push(indexColumnInfo);
});
});
return entities;
}
async GetRelations(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
async GetRelations(
entities: EntityInfo[],
schema: string
): Promise<EntityInfo[]> {
let response: {
tablewithforeignkey: string, fk_partno: number, foreignkeycolumn: string,
tablereferenced: string, foreignkeycolumnreferenced: string,
ondelete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION",
onupdate: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION", object_id: string
}[]
= (await this.Connection.query(`SELECT
tablewithforeignkey: string;
fk_partno: number;
foreignkeycolumn: string;
tablereferenced: string;
foreignkeycolumnreferenced: string;
ondelete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
onupdate: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
object_id: string;
}[] = (await this.Connection.query(`SELECT
con.relname AS tablewithforeignkey,
att.attnum as fk_partno,
att2.attname AS foreignkeycolumn,
@ -329,10 +379,10 @@ export class PostgresDriver extends AbstractDriver {
AND att2.attnum = con.parent
and rc.constraint_name= con.conname`)).rows;
let relationsTemp: RelationTempInfo[] = <RelationTempInfo[]>[];
response.forEach((resp) => {
let rels = relationsTemp.find((val) => {
response.forEach(resp => {
let rels = relationsTemp.find(val => {
return val.object_id == resp.object_id;
})
});
if (rels == undefined) {
rels = <RelationTempInfo>{};
rels.ownerColumnsNames = [];
@ -346,125 +396,164 @@ export class PostgresDriver extends AbstractDriver {
}
rels.ownerColumnsNames.push(resp.foreignkeycolumn);
rels.referencedColumnsNames.push(resp.foreignkeycolumnreferenced);
})
relationsTemp.forEach((relationTmp) => {
let ownerEntity = entities.find((entitity) => {
});
relationsTemp.forEach(relationTmp => {
let ownerEntity = entities.find(entitity => {
return entitity.EntityName == relationTmp.ownerTable;
})
});
if (!ownerEntity) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity model ${relationTmp.ownerTable}.`
);
return;
}
let referencedEntity = entities.find((entitity) => {
let referencedEntity = entities.find(entitity => {
return entitity.EntityName == relationTmp.referencedTable;
})
});
if (!referencedEntity) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity model ${relationTmp.referencedTable}.`
);
return;
}
let ownerColumn = ownerEntity.Columns.find((column) => {
let ownerColumn = ownerEntity.Columns.find(column => {
return column.name == relationTmp.ownerColumnsNames[0];
})
});
if (!ownerColumn) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity column ${
relationTmp.ownerTable
}.${ownerColumn}.`
);
return;
}
let relatedColumn = referencedEntity.Columns.find((column) => {
let relatedColumn = referencedEntity.Columns.find(column => {
return column.name == relationTmp.referencedColumnsNames[0];
})
});
if (!relatedColumn) {
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
TomgUtils.LogFatalError(
`Relation between tables ${relationTmp.ownerTable} and ${
relationTmp.referencedTable
} didn't found entity column ${
relationTmp.referencedTable
}.${relatedColumn}.`
);
return;
}
let ownColumn: ColumnInfo = ownerColumn;
let isOneToMany: boolean;
isOneToMany = false;
let index = ownerEntity.Indexes.find(
(index) => {
return index.isUnique && index.columns.some(col => {
return col.name == ownerColumn!.name
let index = ownerEntity.Indexes.find(index => {
return (
index.isUnique &&
index.columns.some(col => {
return col.name == ownerColumn!.name;
})
}
)
);
});
if (!index) {
isOneToMany = true;
} else {
isOneToMany = false;
}
let ownerRelation = new RelationInfo()
let columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '')
if (referencedEntity.Columns.filter((filterVal) => {
return filterVal.name == columnName;
}).length > 0) {
let ownerRelation = new RelationInfo();
let columnName =
ownerEntity.EntityName.toLowerCase() + (isOneToMany ? "s" : "");
if (
referencedEntity.Columns.filter(filterVal => {
return filterVal.name == columnName;
}).length > 0
) {
for (let i = 2; i <= ownerEntity.Columns.length; i++) {
columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '') + i.toString();
if (referencedEntity.Columns.filter((filterVal) => {
return filterVal.name == columnName;
}).length == 0) break;
columnName =
ownerEntity.EntityName.toLowerCase() +
(isOneToMany ? "s" : "") +
i.toString();
if (
referencedEntity.Columns.filter(filterVal => {
return filterVal.name == columnName;
}).length == 0
)
break;
}
}
ownerRelation.actionOnDelete = relationTmp.actionOnDelete
ownerRelation.actionOnUpdate = relationTmp.actionOnUpdate
ownerRelation.isOwner = true
ownerRelation.relatedColumn = relatedColumn.name.toLowerCase()
ownerRelation.relatedTable = relationTmp.referencedTable
ownerRelation.ownerTable = relationTmp.ownerTable
ownerRelation.ownerColumn = columnName
ownerRelation.relationType = isOneToMany ? "ManyToOne" : "OneToOne"
ownerColumn.relations.push(ownerRelation)
ownerRelation.actionOnDelete = relationTmp.actionOnDelete;
ownerRelation.actionOnUpdate = relationTmp.actionOnUpdate;
ownerRelation.isOwner = true;
ownerRelation.relatedColumn = relatedColumn.name.toLowerCase();
ownerRelation.relatedTable = relationTmp.referencedTable;
ownerRelation.ownerTable = relationTmp.ownerTable;
ownerRelation.ownerColumn = columnName;
ownerRelation.relationType = isOneToMany ? "ManyToOne" : "OneToOne";
ownerColumn.relations.push(ownerRelation);
if (isOneToMany) {
let col = new ColumnInfo()
col.name = columnName
let col = new ColumnInfo();
col.name = columnName;
let referencedRelation = new RelationInfo();
col.relations.push(referencedRelation)
referencedRelation.actionondelete = relationTmp.actionOnDelete
referencedRelation.actiononupdate = relationTmp.actionOnUpdate
referencedRelation.isOwner = false
referencedRelation.relatedColumn = ownerColumn.name
referencedRelation.relatedTable = relationTmp.ownerTable
referencedRelation.ownerTable = relationTmp.referencedTable
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase()
referencedRelation.relationType = "OneToMany"
referencedEntity.Columns.push(col)
col.relations.push(referencedRelation);
referencedRelation.actionondelete = relationTmp.actionOnDelete;
referencedRelation.actiononupdate = relationTmp.actionOnUpdate;
referencedRelation.isOwner = false;
referencedRelation.relatedColumn = ownerColumn.name;
referencedRelation.relatedTable = relationTmp.ownerTable;
referencedRelation.ownerTable = relationTmp.referencedTable;
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase();
referencedRelation.relationType = "OneToMany";
referencedEntity.Columns.push(col);
} else {
let col = new ColumnInfo()
col.name = columnName
let col = new ColumnInfo();
col.name = columnName;
let referencedRelation = new RelationInfo();
col.relations.push(referencedRelation)
referencedRelation.actionondelete = relationTmp.actionOnDelete
referencedRelation.actiononupdate = relationTmp.actionOnUpdate
referencedRelation.isOwner = false
referencedRelation.relatedColumn = ownerColumn.name
referencedRelation.relatedTable = relationTmp.ownerTable
referencedRelation.ownerTable = relationTmp.referencedTable
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase()
referencedRelation.relationType = "OneToOne"
col.relations.push(referencedRelation);
referencedRelation.actionondelete = relationTmp.actionOnDelete;
referencedRelation.actiononupdate = relationTmp.actionOnUpdate;
referencedRelation.isOwner = false;
referencedRelation.relatedColumn = ownerColumn.name;
referencedRelation.relatedTable = relationTmp.ownerTable;
referencedRelation.ownerTable = relationTmp.referencedTable;
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase();
referencedRelation.relationType = "OneToOne";
referencedEntity.Columns.push(col)
referencedEntity.Columns.push(col);
}
})
});
return entities;
}
async DisconnectFromServer() {
if (this.Connection) {
let promise = new Promise<boolean>(
(resolve, reject) => {
this.Connection.end((err) => {
if (!err) {
//Connection successfull
resolve(true)
}
else {
TomgUtils.LogFatalError('Error connecting to Postgres Server.', false, err.message)
reject(err)
}
});
})
let promise = new Promise<boolean>((resolve, reject) => {
this.Connection.end(err => {
if (!err) {
//Connection successfull
resolve(true);
} else {
TomgUtils.LogFatalError(
"Error connecting to Postgres Server.",
false,
err.message
);
reject(err);
}
});
});
await promise;
}
}
async ConnectToServer(database: string, server: string, port: number, user: string, password: string, ssl: boolean) {
async ConnectToServer(
database: string,
server: string,
port: number,
user: string,
password: string,
ssl: boolean
) {
this.Connection = new PG.Client({
database: database,
host: server,
@ -472,39 +561,40 @@ export class PostgresDriver extends AbstractDriver {
user: user,
password: password,
ssl: ssl
})
});
let promise = new Promise<boolean>(
(resolve, reject) => {
this.Connection.connect((err) => {
if (!err) {
//Connection successfull
resolve(true)
}
else {
TomgUtils.LogFatalError('Error connecting to Postgres Server.', false, err.message)
reject(err)
}
});
}
)
let promise = new Promise<boolean>((resolve, reject) => {
this.Connection.connect(err => {
if (!err) {
//Connection successfull
resolve(true);
} else {
TomgUtils.LogFatalError(
"Error connecting to Postgres Server.",
false,
err.message
);
reject(err);
}
});
});
await promise;
}
async CreateDB(dbName: string) {
let resp = await this.Connection.query(`CREATE DATABASE ${dbName}; `)
let resp = await this.Connection.query(`CREATE DATABASE ${dbName}; `);
}
async UseDB(dbName: string) {
let resp = await this.Connection.query(`USE ${dbName}; `)
let resp = await this.Connection.query(`USE ${dbName}; `);
}
async DropDB(dbName: string) {
let resp = await this.Connection.query(`DROP DATABASE ${dbName}; `)
let resp = await this.Connection.query(`DROP DATABASE ${dbName}; `);
}
async CheckIfDBExists(dbName: string): Promise<boolean> {
let resp = await this.Connection.query(`SELECT datname FROM pg_database WHERE datname ='${dbName}' `)
let resp = await this.Connection.query(
`SELECT datname FROM pg_database WHERE datname ='${dbName}' `
);
return resp.rowCount > 0;
}
}

View File

@ -1,136 +1,137 @@
import { AbstractDriver } from "./drivers/AbstractDriver";
import { MssqlDriver } from './drivers/MssqlDriver';
import { MssqlDriver } from "./drivers/MssqlDriver";
import { PostgresDriver } from "./drivers/PostgresDriver";
import { MysqlDriver } from "./drivers/MysqlDriver";
import { MariaDbDriver } from "./drivers/MariaDbDriver";
import { OracleDriver } from "./drivers/OracleDriver";
import { Engine } from './Engine'
import * as Yargs from 'yargs'
import * as TomgUtils from './Utils'
import path = require('path')
import { Engine } from "./Engine";
import * as Yargs from "yargs";
import * as TomgUtils from "./Utils";
import path = require("path");
var argv = Yargs
.usage('Usage: typeorm-model-generator -h <host> -d <database> -p [port] -u <user> -x [password] -e [engine]')
.option('h', {
alias: 'host',
describe: 'IP adress/Hostname for database server.',
var argv = Yargs.usage(
"Usage: typeorm-model-generator -h <host> -d <database> -p [port] -u <user> -x [password] -e [engine]"
)
.option("h", {
alias: "host",
describe: "IP adress/Hostname for database server.",
demand: true
})
.option('d', {
alias: 'database',
describe: 'Database name.',
.option("d", {
alias: "database",
describe: "Database name.",
demand: true
})
.option('u', {
alias: 'user',
describe: 'Username for database server.',
.option("u", {
alias: "user",
describe: "Username for database server.",
demand: true
})
.option('x', {
alias: 'pass',
describe: 'Password for database server.',
default: ''
.option("x", {
alias: "pass",
describe: "Password for database server.",
default: ""
})
.option('p', {
alias: 'port',
describe: 'Port number for database server.',
.option("p", {
alias: "port",
describe: "Port number for database server."
})
.option('e', {
alias: 'engine',
describe: 'Database engine.',
choices: ['mssql', 'postgres', 'mysql', 'mariadb'],
default: 'mssql'
.option("e", {
alias: "engine",
describe: "Database engine.",
choices: ["mssql", "postgres", "mysql", "mariadb"],
default: "mssql"
})
.option('o', {
alias: 'output',
describe: 'Where to place generated models.',
default: path.resolve(process.cwd(), 'output')
.option("o", {
alias: "output",
describe: "Where to place generated models.",
default: path.resolve(process.cwd(), "output")
})
.option('s', {
alias: 'schema',
describe: 'Schema name to create model from. Only for mssql and postgres.'
.option("s", {
alias: "schema",
describe:
"Schema name to create model from. Only for mssql and postgres."
})
.option('ssl', {
.option("ssl", {
boolean: true,
default: false
})
.option('noConfig', {
.option("noConfig", {
boolean: true,
describe: `Doesn't create tsconfig.json and ormconfig.json`,
default: false
})
.option('cf', {
alias: 'case-file',
describe: 'Convert file names to specified case',
choices: ['pascal', 'param', 'camel', 'none'],
default: 'none'
.option("cf", {
alias: "case-file",
describe: "Convert file names to specified case",
choices: ["pascal", "param", "camel", "none"],
default: "none"
})
.option('ce', {
alias: 'case-entity',
describe: 'Convert class names to specified case',
choices: ['pascal', 'camel', 'none'],
default: 'none'
.option("ce", {
alias: "case-entity",
describe: "Convert class names to specified case",
choices: ["pascal", "camel", "none"],
default: "none"
})
.option('cp', {
alias: 'case-property',
describe: 'Convert property names to specified case',
choices: ['pascal', 'camel', 'none'],
default: 'none'
})
.argv;
.option("cp", {
alias: "case-property",
describe: "Convert property names to specified case",
choices: ["pascal", "camel", "none"],
default: "none"
}).argv;
var driver: AbstractDriver;
var standardPort: number;
var standardSchema: string = '';
var standardSchema: string = "";
switch (argv.e) {
case 'mssql':
case "mssql":
driver = new MssqlDriver();
standardPort = 1433;
standardSchema = 'dbo';
standardSchema = "dbo";
break;
case 'postgres':
case "postgres":
driver = new PostgresDriver();
standardPort = 5432;
standardSchema = 'public';
standardSchema = "public";
break;
case 'mysql':
case "mysql":
driver = new MysqlDriver();
standardPort = 3306;
break;
case 'mariadb':
case "mariadb":
driver = new MysqlDriver();
standardPort = 3306;
break;
case 'oracle':
case "oracle":
driver = new OracleDriver();
standardPort = 1521;
break;
default:
TomgUtils.LogFatalError('Database engine not recognized.', false)
throw new Error('Database engine not recognized.');
TomgUtils.LogFatalError("Database engine not recognized.", false);
throw new Error("Database engine not recognized.");
}
let engine = new Engine(
driver, {
host: argv.h,
port: parseInt(argv.p) || standardPort,
databaseName: argv.d,
user: argv.u,
password: argv.x,
databaseType: argv.e,
resultsPath: argv.o,
schemaName: argv.s || standardSchema,
ssl: argv.ssl,
noConfigs: argv.noConfig,
convertCaseFile: argv.cf,
convertCaseEntity: argv.ce,
convertCaseProperty: argv.cp,
});
let engine = new Engine(driver, {
host: argv.h,
port: parseInt(argv.p) || standardPort,
databaseName: argv.d,
user: argv.u,
password: argv.x,
databaseType: argv.e,
resultsPath: argv.o,
schemaName: argv.s || standardSchema,
ssl: argv.ssl,
noConfigs: argv.noConfig,
convertCaseFile: argv.cf,
convertCaseEntity: argv.ce,
convertCaseProperty: argv.cp
});
console.log(`[${new Date().toLocaleTimeString()}] Starting creation of model classes.`);
console.log(
`[${new Date().toLocaleTimeString()}] Starting creation of model classes.`
);
engine.createModelFromDatabase().then(() => {
console.info(`[${new Date().toLocaleTimeString()}] Typeorm model classes created.`)
})
console.info(
`[${new Date().toLocaleTimeString()}] Typeorm model classes created.`
);
});

View File

@ -1,13 +1,22 @@
import { RelationInfo } from './RelationInfo'
import { ColumnType } from 'typeorm';
import { RelationInfo } from "./RelationInfo";
import { ColumnType } from "typeorm";
/**
* ColumnInfo
*/
export class ColumnInfo {
name: string = '';
name: string = "";
default: string | null = null;
is_nullable: boolean = false;
ts_type: 'number' | 'string' | 'boolean' | 'Date' | 'Buffer' | 'Object' | 'string | Object' | 'string | string[]' | 'any';
ts_type:
| "number"
| "string"
| "boolean"
| "Date"
| "Buffer"
| "Object"
| "string | Object"
| "string | string[]"
| "any";
sql_type: ColumnType;
char_max_lenght: number | null = null;
isPrimary: boolean = false;
@ -17,9 +26,7 @@ export class ColumnInfo {
enumOptions: string | null = null;
relations: RelationInfo[];
constructor() {
this.relations = [];
}
}

View File

@ -1,18 +1,23 @@
import { EntityInfo } from './EntityInfo'
import { EntityInfo } from "./EntityInfo";
export class DatabaseModel {
entities: EntityInfo[];
config: {
cascadeInsert: boolean,
cascadeUpdate: boolean,
cascadeRemove: boolean,
}
cascadeInsert: boolean;
cascadeUpdate: boolean;
cascadeRemove: boolean;
};
//TODO:check if unused
//TODO:check if unused
relationImports(): any {
let that = this;
return function (text, render) {
if ('l' != render(text)) return `import {{curly true}}{{toEntityName ${render(text)}}}{{curly false}} from "./{{ ${render( "toFileName"+ text)}}}`
else return '';
}
return function(text, render) {
if ("l" != render(text))
return `import {{curly true}}{{toEntityName ${render(
text
)}}}{{curly false}} from "./{{ ${render(
"toFileName" + text
)}}}`;
else return "";
};
}
}

View File

@ -1,5 +1,5 @@
import { ColumnInfo } from './ColumnInfo'
import * as Handlebars from 'handlebars'
import { ColumnInfo } from "./ColumnInfo";
import * as Handlebars from "handlebars";
/**
* EntityInfo
@ -14,17 +14,14 @@ export class EntityInfo {
relationImports(): any {
var returnString = "";
var imports: string[] = [];
this.Columns.forEach((column) => {
column.relations.forEach(
(relation) => {
if (this.EntityName != relation.relatedTable)
imports.push(relation.relatedTable);
}
)
this.Columns.forEach(column => {
column.relations.forEach(relation => {
if (this.EntityName != relation.relatedTable)
imports.push(relation.relatedTable);
});
});
this.UniqueImports=imports.filter(function (elem, index, self) {
this.UniqueImports = imports.filter(function(elem, index, self) {
return index == self.indexOf(elem);
})
});
}
}

View File

@ -1,5 +1,5 @@
interface IndexColumnInfo {
name: string,
name: string;
//isDescending:boolean,
// isIncludedColumn:boolean
}

View File

@ -2,8 +2,8 @@
* IndexInfo
*/
interface IndexInfo {
name: string,
columns: IndexColumnInfo[],
isUnique: boolean,
isPrimaryKey: boolean,
name: string;
columns: IndexColumnInfo[];
isUnique: boolean;
isPrimaryKey: boolean;
}

View File

@ -1,17 +1,16 @@
export class RelationInfo {
[x: string]: any;
isOwner: boolean
relationType: "OneToOne" | "OneToMany" | "ManyToOne"
relatedTable: string
relatedColumn: string
ownerTable: string
ownerColumn: string
actionOnDelete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION"
actionOnUpdate: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION"
isOwner: boolean;
relationType: "OneToOne" | "OneToMany" | "ManyToOne";
relatedTable: string;
relatedColumn: string;
ownerTable: string;
ownerColumn: string;
actionOnDelete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
actionOnUpdate: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
get isOneToMany(): boolean {
return this.relationType == "OneToMany"
return this.relationType == "OneToMany";
}
}

View File

@ -1,9 +1,9 @@
interface RelationTempInfo {
ownerTable: string,
ownerColumnsNames: string[],
referencedTable: string,
referencedColumnsNames: string[],
actionOnDelete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION",
actionOnUpdate: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION",
object_id: number | string
ownerTable: string;
ownerColumnsNames: string[];
referencedTable: string;
referencedColumnsNames: string[];
actionOnDelete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
actionOnUpdate: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
object_id: number | string;
}