[
  {
    "path": ".editorconfig",
    "content": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# editorconfig.org\n\nroot = true\n\n[*]\n\n# Change these settings to your own preference\nindent_style = space\nindent_size = 4\n\n# We recommend you to keep these unchanged\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.md]\ntrim_trailing_whitespace = false\n\n[{package,bower}.json]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".gitattributes",
    "content": "# All text files should have the \"lf\" (Unix) line endings\n* text eol=lf\n\n# Explicitly declare text files you want to always be normalized and converted\n# to native line endings on checkout.\n*.java text\n*.js text\n*.css text\n*.html text\n\n# Denote all files that are truly binary and should not be modified.\n*.png binary\n*.jpg binary\n*.jpeg binary\n*.gif binary\n*.ico binary\n*.jar binary\n*.pdf binary\n*.eot binary\n*.ttf binary\n*.gzip binary\n*.gz binary\n*.ai binary\n*.eps binary\n*.swf binary\n*.mwb binary"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n- package-ecosystem: maven\n  directory: \"/\"\n  schedule:\n    interval: monthly\n  open-pull-requests-limit: 15\n  groups:\n    maven-dependencies:\n      update-types:\n        - \"patch\"\n        - \"minor\"\n        - \"major\"\n"
  },
  {
    "path": ".github/workflows/maven.yml",
    "content": "name: Java CI\n\non: [push]\n\njobs:\n    build:\n        runs-on: ubuntu-latest\n        steps:\n            - uses: actions/checkout@v3\n            - name: Set up JDK 17\n              uses: actions/setup-java@v3\n              with:\n                  distribution: 'adopt'\n                  java-version: '17'\n                  cache: 'maven'\n            - name: Build and Run Tests\n              run: mvn test --file pom.xml --batch-mode --update-snapshots --fail-at-end\n            - name: Publish Test Report\n              if: ${{ always() }}\n              uses: scacap/action-surefire-report@v1\n"
  },
  {
    "path": ".gitignore",
    "content": "######################\n# Project Specific\n######################\nclasses/artifacts\n/my-project-jdl.jh\n/*.jdl\n/*.jh\n\n######################\n# Eclipse\n######################\n*.pydevproject\n.project\n.metadata\ntmp/\ntmp/**/*\n*.tmp\n*.bak\n*.swp\n*~.nib\nlocal.properties\n.classpath\n.settings/\n.loadpath\n.factorypath\n/src/main/resources/rebel.xml\n\n# External tool builders\n.externalToolBuilders/**\n\n# Locally stored \"Eclipse launch configurations\"\n*.launch\n\n# CDT-specific\n.cproject\n\n# PDT-specific\n.buildpath\n\n######################\n# Intellij\n######################\n.idea/\n*.iml\n*.iws\n*.ipr\n*.ids\n*.orig\n\n######################\n# Visual Studio Code\n######################\n.vscode/\n\n######################\n# Maven\n######################\nlog/\ntarget/\n\n######################\n# Package Files\n######################\n*.jar\n*.war\n*.ear\n*.db\n\n######################\n# Windows\n######################\n# Windows image file caches\nThumbs.db\n\n# Folder config file\nDesktop.ini\n\n######################\n# Mac OSX\n######################\n.DS_Store\n.svn\n\n# Thumbnails\n._*\n\n# Files that might appear on external disk\n.Spotlight-V100\n.Trashes\n\n######################\n# Directories\n######################\n#/build/\n#/bin/\n#/deploy/\n\n######################\n# Logs\n######################\n*.log\n\n######################\n# Others\n######################\n*.class\n*.*~\n*~\n.merge_file*\n\n######################\n# Maven Wrapper\n######################\n!.mvn/wrapper/maven-wrapper.jar\n\n######################\n# ESLint\n######################\n.eslintcache\n"
  },
  {
    "path": ".mvn/wrapper/maven-wrapper.properties",
    "content": "distributionUrl=https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.zip\n"
  },
  {
    "path": ".prettierignore",
    "content": ""
  },
  {
    "path": ".prettierrc",
    "content": "# Prettier configuration\n\nprintWidth: 140\nsingleQuote: true\ntabWidth: 2\nuseTabs: false\n\n# java rules:\noverrides:\n  - files: \"*.java\"\n    options:\n      tabWidth: 4\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: java\n\n#jdk:\n#  - oraclejdk8\n\ncache:\n    directories:\n        - $HOME/.m2\n\nservices:\n  - mysql\n\nbefore_install:\n  - chmod +x mvnw\n\nafter_success:\n  - mvn clean test\n#  - mvn clean test jacoco:report\n#  - mvn clean test jacoco:report coveralls:report\n\n\n#notifications:\n#  email:\n#    - yoann.caplain@blackdread.org\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 Yoann CAPLAIN\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "[![build](https://github.com/Blackdread/sql-to-jdl/actions/workflows/maven.yml/badge.svg)](https://github.com/Blackdread/sql-to-jdl/actions/workflows/maven.yml)\n[![StackShare](https://img.shields.io/badge/tech-stack-0690fa.svg?style=flat)](https://stackshare.io/Blackdread/sql-to-jdl)\n\n# sql-to-jdl\nTool to translate SQL databases to JDL format of jHipster (Created due to existing databases to be generated with jHipster and build angular-java web)\n\n# Usage\n\n```bash\n#Download\ngit clone https://github.com/Blackdread/sql-to-jdl.git\n\n# Modify configuration file application.yml at https://github.com/Blackdread/sql-to-jdl/blob/master/src/main/resources/application.yml\n\n#Build, skip the tests for lack of time\nmvn clean package -DskipTests\n\n#Run\njava -jar target/sql-to-java-*-SNAPSHOT.jar\n```\n\nDirect link to [application.yml](https://github.com/Blackdread/sql-to-jdl/blob/master/src/main/resources/application.yml)\n\n_Don't forget to install git, maven 3 and java 17 before launching_\n\n# Compatibility\nThis implementation works with \n  - mysql 5.7.x, 8.x, 9.x\n  - mariadb 10.x\n  - postgresql 9.x+\n  - oracle 21\n  - MsSQL 2019\n\nHelp is requested on MsSQL and Oracle support.  This will require implementation of SqlJdlTypeService and creating the raw SQL files.  See the MySQL, MariaDB, and PosrgreSQL implemtaitons for examples.\n\n# Testing\nSetting up tests for new databases types or versions is easy.  Have a look existing tests.  \nMsSQL and Oracle have tests created that are disabled because their implementations are incomplete.\n\nTests use liquibase so that most of the setup for tests is database agnostic.  The main exception is for the all types test that is different for each database type.\n\nEach test needs the following files\n  - {{test.name}}-liquibase-changeset.yaml\n  - {{test.name}}-expected.jdl\n  \nTo override the default name the files as\n  - {{test.name}}-liquibase-changeset-{{db.typ}}.yaml\n  - {{test.name}}-expected-{{db.type}}.jdl\n\nIf you need to change the tests run for a specific database type or version, use method hiding by implementing \n\nprivate static Stream<String> provideTestNames() in the subclass of SqlToJdlTransactionPerTestTest\n\nIn order to avoid starting a new database and spring boot container for every test, liquibase is used to roll back the database to an empty state.  This can be done by just rolling back the transaction with Spring, but MySQL does not support rollback of DDL changes.  This works great with PostgreSQL, but liquibase is used to roll back the changes for all database types currently.\n\nCurrently the full test suite runs 11 test per database version which total nearly 80 tests.  \n \n# Why not use tools like UML provided on jHipster?\n- JDL from web is ok for a few entities but not for more than 100 entities and relations\n- UML software and xml exporters could have worked (other tools on jHipster) but:\n  - already many databases in production to be exported in JDL (faster to generate the JDL from it)\n  - already working UML design with MySQL Workbench\n\n# How to use\nJust execute the code from IDE or use \"mvn\" to run the code, it will connect to your DB (see application config yml) and it will generate the JDL.\n\nSet properties file:\n- Schema name to export\n- Tables names to be ignored\n- Path of export file\n- Database object prefixes to remove from entity name\n- Include table name is JDL\n- Undefined JDL type handling to ERROR, SKIP, or UNSUPPORTED\n- Add JDL type overrides if necessary.\n\n# After JDL file is generated\nStill have some manual steps to do:\n- review relations:\n  - ManyToMany\n  - Owner side display field\n  - Inverse side field name and display field\n  - Bidirectional or not\n- add values to enums\n- review validations of entities\n\n# Default specific rules\nTable is treated as enum if only 2 columns and both are: \"id\" AND (\"code\" OR \"name\")\n\nTable is treated as ManyToMany if only 2 columns and both are foreign keys\n\n# Links\n[jHipster JDL](https://www.jhipster.tech/jdl/intro)\n\n# An alternative for REST filter and sort\nDifferent criterias, support for JPA and jOOQ dynamic filtering and sorting.\n\nhttps://github.com/Blackdread/rest-filter\n"
  },
  {
    "path": "checkstyle-suppressions.xml",
    "content": "<?xml version=\"1.0\"?>\n\n<!DOCTYPE suppressions PUBLIC\n    \"-//Checkstyle//DTD SuppressionFilter Configuration 1.0//EN\"\n    \"https://checkstyle.org/dtds/suppressions_1_0.dtd\">\n\n<suppressions>\n    <suppress checks=\".*\"\n              files=\".[/\\\\]src[/\\\\]main[/\\\\]java[/\\\\]org[/\\\\]blackdread[/\\\\]sqltojava[/\\\\]jooq[/\\\\]generated[/\\\\]\"/>\n</suppressions>\n"
  },
  {
    "path": "checkstyle.xml",
    "content": "<?xml version=\"1.0\"?>\n<!DOCTYPE module PUBLIC\n    \"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN\"\n    \"https://checkstyle.org/dtds/configuration_1_3.dtd\">\n\n<module name = \"Checker\">\n    <property name=\"charset\" value=\"UTF-8\"/>\n\n    <property name=\"severity\" value=\"error\"/>\n\n    <property name=\"fileExtensions\" value=\"java, properties, xml\"/>\n    <module name=\"BeforeExecutionExclusionFileFilter\">\n        <property name=\"fileNamePattern\" value=\"module\\-info\\.java$\"/>\n    </module>\n\n    <module name=\"TreeWalker\">\n        <module name=\"OuterTypeFilename\"/>\n        <module name=\"NoLineWrap\">\n            <property name=\"tokens\" value=\"PACKAGE_DEF, IMPORT, STATIC_IMPORT\"/>\n        </module>\n        <module name=\"LeftCurly\" />\n        <module name=\"RightCurly\" />\n        <module name=\"WhitespaceAfter\"/>\n        <module name=\"WhitespaceAround\">\n            <property name=\"allowEmptyConstructors\" value=\"true\"/>\n            <property name=\"allowEmptyLambdas\" value=\"true\"/>\n            <property name=\"allowEmptyMethods\" value=\"true\"/>\n            <property name=\"allowEmptyTypes\" value=\"true\"/>\n            <property name=\"allowEmptyLoops\" value=\"true\"/>\n            <property name=\"allowEmptyCatches\" value=\"true\"/>\n            <property name=\"ignoreEnhancedForColon\" value=\"false\"/>\n            <property name=\"tokens\"\n                      value=\"ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR,\n                    BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAMBDA, LAND,\n                    LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY,\n                    LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SWITCH, LITERAL_SYNCHRONIZED,\n                    LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN,\n                    NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR,\n                    SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND\"/>\n            <message key=\"ws.notFollowed\"\n                     value=\"WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)\"/>\n            <message key=\"ws.notPreceded\"\n                     value=\"WhitespaceAround: ''{0}'' is not preceded with whitespace.\"/>\n        </module>\n        <module name=\"GenericWhitespace\">\n            <message key=\"ws.followed\"\n                     value=\"GenericWhitespace ''{0}'' is followed by whitespace.\"/>\n            <message key=\"ws.preceded\"\n                     value=\"GenericWhitespace ''{0}'' is preceded with whitespace.\"/>\n            <message key=\"ws.illegalFollow\"\n                     value=\"GenericWhitespace ''{0}'' should followed by whitespace.\"/>\n            <message key=\"ws.notPreceded\"\n                     value=\"GenericWhitespace ''{0}'' is not preceded with whitespace.\"/>\n        </module>\n        <module name=\"OneStatementPerLine\"/>\n        <module name=\"ModifierOrder\"/>\n        <module name=\"EmptyLineSeparator\">\n            <property name=\"tokens\"\n                      value=\"PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,\n                    STATIC_INIT, INSTANCE_INIT, CTOR_DEF, VARIABLE_DEF, RECORD_DEF,\n                    COMPACT_CTOR_DEF\"/>\n            <property name=\"allowNoEmptyLineBetweenFields\" value=\"true\"/>\n        </module>\n        <module name=\"SeparatorWrap\">\n            <property name=\"id\" value=\"SeparatorWrapDot\"/>\n            <property name=\"tokens\" value=\"DOT\"/>\n            <property name=\"option\" value=\"nl\"/>\n        </module>\n        <module name=\"SeparatorWrap\">\n            <property name=\"id\" value=\"SeparatorWrapComma\"/>\n            <property name=\"tokens\" value=\"COMMA\"/>\n            <property name=\"option\" value=\"EOL\"/>\n        </module>\n\n        <module name=\"CustomImportOrder\">\n            <property name=\"sortImportsInGroupAlphabetically\" value=\"true\"/>\n            <property name=\"separateLineBetweenGroups\" value=\"true\"/>\n            <property name=\"customImportOrderRules\" value=\"STATIC###THIRD_PARTY_PACKAGE\"/>\n            <property name=\"tokens\" value=\"IMPORT, STATIC_IMPORT, PACKAGE_DEF\"/>\n        </module>\n        <module name=\"MethodParamPad\">\n            <property name=\"tokens\"\n                      value=\"CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF,\n                    SUPER_CTOR_CALL, ENUM_CONSTANT_DEF, RECORD_DEF\"/>\n        </module>\n        <module name=\"NoWhitespaceBefore\">\n            <property name=\"tokens\"\n                      value=\"COMMA, SEMI, POST_INC, POST_DEC, DOT,\n                    LABELED_STAT, METHOD_REF\"/>\n            <property name=\"allowLineBreaks\" value=\"true\"/>\n        </module>\n        <module name=\"ParenPad\"/>\n        <module name=\"AnnotationLocation\">\n            <property name=\"allowSamelineMultipleAnnotations\" value=\"false\"/>\n            <property name=\"allowSamelineSingleParameterlessAnnotation\" value=\"false\"/>\n            <property name=\"allowSamelineParameterizedAnnotation\" value=\"false\"/>\n        </module>\n    </module>\n</module>\n"
  },
  {
    "path": "mvnw",
    "content": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# ----------------------------------------------------------------------------\n\n# ----------------------------------------------------------------------------\n# Maven2 Start Up Batch script\n#\n# Required ENV vars:\n# ------------------\n#   JAVA_HOME - location of a JDK home dir\n#\n# Optional ENV vars\n# -----------------\n#   M2_HOME - location of maven2's installed home dir\n#   MAVEN_OPTS - parameters passed to the Java VM when running Maven\n#     e.g. to debug Maven itself, use\n#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n# ----------------------------------------------------------------------------\n\nif [ -z \"$MAVEN_SKIP_RC\" ] ; then\n\n  if [ -f /etc/mavenrc ] ; then\n    . /etc/mavenrc\n  fi\n\n  if [ -f \"$HOME/.mavenrc\" ] ; then\n    . \"$HOME/.mavenrc\"\n  fi\n\nfi\n\n# OS specific support.  $var _must_ be set to either true or false.\ncygwin=false;\ndarwin=false;\nmingw=false\ncase \"`uname`\" in\n  CYGWIN*) cygwin=true ;;\n  MINGW*) mingw=true;;\n  Darwin*) darwin=true\n    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home\n    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html\n    if [ -z \"$JAVA_HOME\" ]; then\n      if [ -x \"/usr/libexec/java_home\" ]; then\n        export JAVA_HOME=\"`/usr/libexec/java_home`\"\n      else\n        export JAVA_HOME=\"/Library/Java/Home\"\n      fi\n    fi\n    ;;\nesac\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  if [ -r /etc/gentoo-release ] ; then\n    JAVA_HOME=`java-config --jre-home`\n  fi\nfi\n\nif [ -z \"$M2_HOME\" ] ; then\n  ## resolve links - $0 may be a link to maven's home\n  PRG=\"$0\"\n\n  # need this for relative symlinks\n  while [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n      PRG=\"$link\"\n    else\n      PRG=\"`dirname \"$PRG\"`/$link\"\n    fi\n  done\n\n  saveddir=`pwd`\n\n  M2_HOME=`dirname \"$PRG\"`/..\n\n  # make it fully qualified\n  M2_HOME=`cd \"$M2_HOME\" && pwd`\n\n  cd \"$saveddir\"\n  # echo Using m2 at $M2_HOME\nfi\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched\nif $cygwin ; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=`cygpath --unix \"$M2_HOME\"`\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --unix \"$CLASSPATH\"`\nfi\n\n# For Migwn, ensure paths are in UNIX format before anything is touched\nif $mingw ; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=\"`(cd \"$M2_HOME\"; pwd)`\"\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=\"`(cd \"$JAVA_HOME\"; pwd)`\"\n  # TODO classpath?\nfi\n\nif [ -z \"$JAVA_HOME\" ]; then\n  javaExecutable=\"`which javac`\"\n  if [ -n \"$javaExecutable\" ] && ! [ \"`expr \\\"$javaExecutable\\\" : '\\([^ ]*\\)'`\" = \"no\" ]; then\n    # readlink(1) is not available as standard on Solaris 10.\n    readLink=`which readlink`\n    if [ ! `expr \"$readLink\" : '\\([^ ]*\\)'` = \"no\" ]; then\n      if $darwin ; then\n        javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n        javaExecutable=\"`cd \\\"$javaHome\\\" && pwd -P`/javac\"\n      else\n        javaExecutable=\"`readlink -f \\\"$javaExecutable\\\"`\"\n      fi\n      javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n      javaHome=`expr \"$javaHome\" : '\\(.*\\)/bin'`\n      JAVA_HOME=\"$javaHome\"\n      export JAVA_HOME\n    fi\n  fi\nfi\n\nif [ -z \"$JAVACMD\" ] ; then\n  if [ -n \"$JAVA_HOME\"  ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n      # IBM's JDK on AIX uses strange locations for the executables\n      JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n      JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n  else\n    JAVACMD=\"`which java`\"\n  fi\nfi\n\nif [ ! -x \"$JAVACMD\" ] ; then\n  echo \"Error: JAVA_HOME is not defined correctly.\" >&2\n  echo \"  We cannot execute $JAVACMD\" >&2\n  exit 1\nfi\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  echo \"Warning: JAVA_HOME environment variable is not set.\"\nfi\n\nCLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher\n\n# traverses directory structure from process work directory to filesystem root\n# first directory with .mvn subdirectory is considered project base directory\nfind_maven_basedir() {\n\n  if [ -z \"$1\" ]\n  then\n    echo \"Path not specified to find_maven_basedir\"\n    return 1\n  fi\n\n  basedir=\"$1\"\n  wdir=\"$1\"\n  while [ \"$wdir\" != '/' ] ; do\n    if [ -d \"$wdir\"/.mvn ] ; then\n      basedir=$wdir\n      break\n    fi\n    # workaround for JBEAP-8937 (on Solaris 10/Sparc)\n    if [ -d \"${wdir}\" ]; then\n      wdir=`cd \"$wdir/..\"; pwd`\n    fi\n    # end of workaround\n  done\n  echo \"${basedir}\"\n}\n\n# concatenates all lines of a file\nconcat_lines() {\n  if [ -f \"$1\" ]; then\n    echo \"$(tr -s '\\n' ' ' < \"$1\")\"\n  fi\n}\n\nBASE_DIR=`find_maven_basedir \"$(pwd)\"`\nif [ -z \"$BASE_DIR\" ]; then\n  exit 1;\nfi\n\nexport MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-\"$BASE_DIR\"}\necho $MAVEN_PROJECTBASEDIR\nMAVEN_OPTS=\"$(concat_lines \"$MAVEN_PROJECTBASEDIR/.mvn/jvm.config\") $MAVEN_OPTS\"\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=`cygpath --path --windows \"$M2_HOME\"`\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --path --windows \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --windows \"$CLASSPATH\"`\n  [ -n \"$MAVEN_PROJECTBASEDIR\" ] &&\n    MAVEN_PROJECTBASEDIR=`cygpath --path --windows \"$MAVEN_PROJECTBASEDIR\"`\nfi\n\nWRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\nexec \"$JAVACMD\" \\\n  $MAVEN_OPTS \\\n  -classpath \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\" \\\n  \"-Dmaven.home=${M2_HOME}\" \"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}\" \\\n  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG \"$@\"\n"
  },
  {
    "path": "mvnw.cmd",
    "content": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software Foundation (ASF) under one\n@REM or more contributor license agreements.  See the NOTICE file\n@REM distributed with this work for additional information\n@REM regarding copyright ownership.  The ASF licenses this file\n@REM to you under the Apache License, Version 2.0 (the\n@REM \"License\"); you may not use this file except in compliance\n@REM with the License.  You may obtain a copy of the License at\n@REM\n@REM    http://www.apache.org/licenses/LICENSE-2.0\n@REM\n@REM Unless required by applicable law or agreed to in writing,\n@REM software distributed under the License is distributed on an\n@REM \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n@REM KIND, either express or implied.  See the License for the\n@REM specific language governing permissions and limitations\n@REM under the License.\n@REM ----------------------------------------------------------------------------\n\n@REM ----------------------------------------------------------------------------\n@REM Maven2 Start Up Batch script\n@REM\n@REM Required ENV vars:\n@REM JAVA_HOME - location of a JDK home dir\n@REM\n@REM Optional ENV vars\n@REM M2_HOME - location of maven2's installed home dir\n@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands\n@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending\n@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven\n@REM     e.g. to debug Maven itself, use\n@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n@REM ----------------------------------------------------------------------------\n\n@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'\n@echo off\n@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'\n@if \"%MAVEN_BATCH_ECHO%\" == \"on\"  echo %MAVEN_BATCH_ECHO%\n\n@REM set %HOME% to equivalent of $HOME\nif \"%HOME%\" == \"\" (set \"HOME=%HOMEDRIVE%%HOMEPATH%\")\n\n@REM Execute a user defined script before this one\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPre\n@REM check for pre script, once with legacy .bat ending and once with .cmd ending\nif exist \"%HOME%\\mavenrc_pre.bat\" call \"%HOME%\\mavenrc_pre.bat\"\nif exist \"%HOME%\\mavenrc_pre.cmd\" call \"%HOME%\\mavenrc_pre.cmd\"\n:skipRcPre\n\n@setlocal\n\nset ERROR_CODE=0\n\n@REM To isolate internal variables from possible post scripts, we use another setlocal\n@setlocal\n\n@REM ==== START VALIDATION ====\nif not \"%JAVA_HOME%\" == \"\" goto OkJHome\n\necho.\necho Error: JAVA_HOME not found in your environment. >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n:OkJHome\nif exist \"%JAVA_HOME%\\bin\\java.exe\" goto init\n\necho.\necho Error: JAVA_HOME is set to an invalid directory. >&2\necho JAVA_HOME = \"%JAVA_HOME%\" >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n@REM ==== END VALIDATION ====\n\n:init\n\n@REM Find the project base dir, i.e. the directory that contains the folder \".mvn\".\n@REM Fallback to current working directory if not found.\n\nset MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%\nIF NOT \"%MAVEN_PROJECTBASEDIR%\"==\"\" goto endDetectBaseDir\n\nset EXEC_DIR=%CD%\nset WDIR=%EXEC_DIR%\n:findBaseDir\nIF EXIST \"%WDIR%\"\\.mvn goto baseDirFound\ncd ..\nIF \"%WDIR%\"==\"%CD%\" goto baseDirNotFound\nset WDIR=%CD%\ngoto findBaseDir\n\n:baseDirFound\nset MAVEN_PROJECTBASEDIR=%WDIR%\ncd \"%EXEC_DIR%\"\ngoto endDetectBaseDir\n\n:baseDirNotFound\nset MAVEN_PROJECTBASEDIR=%EXEC_DIR%\ncd \"%EXEC_DIR%\"\n\n:endDetectBaseDir\n\nIF NOT EXIST \"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\" goto endReadAdditionalConfig\n\n@setlocal EnableExtensions EnableDelayedExpansion\nfor /F \"usebackq delims=\" %%a in (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a\n@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%\n\n:endReadAdditionalConfig\n\nSET MAVEN_JAVA_EXE=\"%JAVA_HOME%\\bin\\java.exe\"\n\nset WRAPPER_JAR=\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.jar\"\nset WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\n%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% \"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%\" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*\nif ERRORLEVEL 1 goto error\ngoto end\n\n:error\nset ERROR_CODE=1\n\n:end\n@endlocal & set ERROR_CODE=%ERROR_CODE%\n\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPost\n@REM check for post script, once with legacy .bat ending and once with .cmd ending\nif exist \"%HOME%\\mavenrc_post.bat\" call \"%HOME%\\mavenrc_post.bat\"\nif exist \"%HOME%\\mavenrc_post.cmd\" call \"%HOME%\\mavenrc_post.cmd\"\n:skipRcPost\n\n@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'\nif \"%MAVEN_BATCH_PAUSE%\" == \"on\" pause\n\nif \"%MAVEN_TERMINATE_CMD%\" == \"on\" exit %ERROR_CODE%\n\nexit /B %ERROR_CODE%\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-starter-parent</artifactId>\n        <version>2.7.4</version>\n        <relativePath/> <!-- lookup parent from repository -->\n    </parent>\n\n    <groupId>org.blackdread</groupId>\n    <artifactId>sql-to-java</artifactId>\n    <version>1.0-SNAPSHOT</version>\n    <packaging>jar</packaging>\n\n    <name>sql-to-java</name>\n    <description>Sql to JDL project</description>\n\n    <properties>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>\n        <java.version>17</java.version>\n\n        <database.url>jdbc:mysql://localhost:3306/?serverTimezone=UTC</database.url>\n        <database.user>root</database.user>\n        <database.password></database.password>\n\n        <guava.version>33.3.1-jre</guava.version>\n\n        <testcontainers.version>1.17.6</testcontainers.version>\n\n        <!-- By default just re-write code with prettier -->\n        <plugin.prettier.goal>write</plugin.prettier.goal>\n\n        <maven.surefire.plugin.version>3.5.1</maven.surefire.plugin.version>\n        <maven.checkstyle.plugin.version>3.5.0</maven.checkstyle.plugin.version>\n        <liquibase-core.version>4.19.0</liquibase-core.version>\n        <liquibase-maven-plugin.version>4.19.0</liquibase-maven-plugin.version>\n        <checkstyle.version>10.18.2</checkstyle.version>\n        <plugin.checkstyle.goal>check</plugin.checkstyle.goal>\n<!--        <guava.version>31.1-jre</guava.version>-->\n        <mustache.compiler.api.version>0.9.10</mustache.compiler.api.version>\n        <org.mapstruct.version>1.6.2</org.mapstruct.version>\n        <!--<jacoco-plugin.version>0.7.9</jacoco-plugin.version>-->\n        <!--<coveralls-plugin.version>4.3.0</coveralls-plugin.version>-->\n    </properties>\n\n    <scm>\n        <connection>scm:git:https://github.com/Blackdread/sql-to-jdl.git</connection>\n        <developerConnection>scm:git:https://github.com/blackdread/sql-to-jdl.git</developerConnection>\n        <url>https://github.com/blackdread/sql-to-jdl</url>\n    </scm>\n\n    <licenses>\n        <license>\n            <name>MIT</name>\n            <url>https://github.com/Blackdread/sql-to-jdl/blob/master/LICENSE</url>\n            <distribution>repo</distribution>\n        </license>\n    </licenses>\n\n    <developers>\n        <developer>\n            <id>blackdread</id>\n            <name>Yoann CAPLAIN</name>\n            <email>yoann.caplain@blackdread.org</email>\n            <url>http://blackdread.org</url>\n        </developer>\n    </developers>\n\n    <dependencies>\n        <dependency>\n            <groupId>com.google.guava</groupId>\n            <artifactId>guava</artifactId>\n            <version>${guava.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.commons</groupId>\n            <artifactId>commons-lang3</artifactId>\n            <version>3.17.0</version>\n        </dependency>\n        <dependency>\n            <groupId>commons-io</groupId>\n            <artifactId>commons-io</artifactId>\n            <version>2.17.0</version>\n        </dependency>\n<!--        <dependency>-->\n<!--            <groupId>com.google.guava</groupId>-->\n<!--            <artifactId>guava</artifactId>-->\n<!--            <version>${guava.version}</version>-->\n<!--        </dependency>-->\n\n        <dependency>\n            <groupId>com.zaxxer</groupId>\n            <artifactId>HikariCP</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>mysql</groupId>\n            <artifactId>mysql-connector-java</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>com.microsoft.sqlserver</groupId>\n            <artifactId>mssql-jdbc</artifactId>\n            <version>12.4.2.jre11</version>\n            <scope>runtime</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.postgresql</groupId>\n            <artifactId>postgresql</artifactId>\n            <scope>runtime</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.mariadb.jdbc</groupId>\n            <artifactId>mariadb-java-client</artifactId>\n            <scope>runtime</scope>\n        </dependency>\n        <dependency>\n            <groupId>com.oracle.database.jdbc</groupId>\n            <artifactId>ojdbc11</artifactId>\n            <scope>runtime</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-jdbc</artifactId>\n        </dependency>\n\n         <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-aop</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-integration</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.retry</groupId>\n            <artifactId>spring-retry</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-validation</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-devtools</artifactId>\n            <scope>runtime</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-configuration-processor</artifactId>\n            <optional>true</optional>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-test</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.junit.jupiter</groupId>\n            <artifactId>junit-jupiter-api</artifactId>\n            <scope>test</scope>\n        </dependency>\n        <!-- https://mvnrepository.com/artifact/uk.org.webcompere/system-stubs-core -->\n        <dependency>\n            <groupId>uk.org.webcompere</groupId>\n            <artifactId>system-stubs-jupiter</artifactId>\n            <version>2.0.2</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.testcontainers</groupId>\n            <artifactId>testcontainers</artifactId>\n            <version>${testcontainers.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.testcontainers</groupId>\n            <artifactId>junit-jupiter</artifactId>\n            <version>${testcontainers.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.testcontainers</groupId>\n            <artifactId>mysql</artifactId>\n            <version>${testcontainers.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.testcontainers</groupId>\n            <artifactId>mariadb</artifactId>\n            <version>${testcontainers.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.testcontainers</groupId>\n            <artifactId>mssqlserver</artifactId>\n            <version>${testcontainers.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.testcontainers</groupId>\n            <artifactId>postgresql</artifactId>\n            <version>${testcontainers.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.testcontainers</groupId>\n            <artifactId>oracle-xe</artifactId>\n            <version>${testcontainers.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.liquibase</groupId>\n            <artifactId>liquibase-core</artifactId>\n            <version>${liquibase-core.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>com.github.spullara.mustache.java</groupId>\n            <artifactId>compiler</artifactId>\n            <version>${mustache.compiler.api.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.mapstruct</groupId>\n            <artifactId>mapstruct</artifactId>\n            <version>${org.mapstruct.version}</version>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <defaultGoal>spring-boot:run</defaultGoal>\n        <testResources>\n            <testResource>\n                <directory>src/test/resources/</directory>\n            </testResource>\n        </testResources>\n        <plugins>\n            <plugin>\n                <groupId>org.springframework.boot</groupId>\n                <artifactId>spring-boot-maven-plugin</artifactId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <version>${maven.surefire.plugin.version}</version>\n                <configuration>\n                  <forkCount>2.5C</forkCount>\n                  <reuseForks>false</reuseForks>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>com.hubspot.maven.plugins</groupId>\n                <artifactId>prettier-maven-plugin</artifactId>\n                <version>0.22</version>\n                <configuration>\n                  <prettierJavaVersion>1.5.0</prettierJavaVersion>\n                </configuration>\n                <executions>\n                    <execution>\n                        <phase>validate</phase>\n                        <goals>\n                            <goal>${plugin.prettier.goal}</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n                <version>${maven.checkstyle.plugin.version}</version>\n                <dependencies>\n                    <dependency>\n                        <groupId>com.puppycrawl.tools</groupId>\n                        <artifactId>checkstyle</artifactId>\n                        <version>${checkstyle.version}</version>\n                    </dependency>\n                </dependencies>\n                <configuration>\n                    <configLocation>checkstyle.xml</configLocation>\n                    <suppressionsLocation>checkstyle-suppressions.xml</suppressionsLocation>\n                </configuration>\n\n            </plugin>\n            <plugin>\n                <groupId>org.liquibase</groupId>\n                <artifactId>liquibase-maven-plugin</artifactId>\n                <version>${liquibase-maven-plugin.version}</version>\n                <configuration>\n                    <propertyFileWillOverride>true</propertyFileWillOverride>\n                    <propertyFile>src/test/resources/liquibase.properties</propertyFile>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <configuration>\n                    <source>17</source>\n                    <target>17</target>\n                    <annotationProcessorPaths>\n                        <path>\n                            <groupId>org.mapstruct</groupId>\n                            <artifactId>mapstruct-processor</artifactId>\n                            <version>${org.mapstruct.version}</version>\n                        </path>\n                    </annotationProcessorPaths>\n                </configuration>\n            </plugin>\n            <!--<plugin>-->\n            <!--<groupId>org.jacoco</groupId>-->\n            <!--<artifactId>jacoco-maven-plugin</artifactId>-->\n            <!--<version>${jacoco-plugin.version}</version>-->\n            <!--<executions>-->\n            <!--<execution>-->\n            <!--<id>prepare-agent</id>-->\n            <!--<goals>-->\n            <!--<goal>prepare-agent</goal>-->\n            <!--</goals>-->\n            <!--</execution>-->\n            <!--</executions>-->\n            <!--</plugin>-->\n        </plugins>\n    </build>\n\n    <repositories>\n        <repository>\n            <id>spring-snapshots</id>\n            <name>Spring Snapshots</name>\n            <url>https://repo.spring.io/snapshot</url>\n            <snapshots>\n                <enabled>true</enabled>\n            </snapshots>\n        </repository>\n        <repository>\n            <id>spring-milestones</id>\n            <name>Spring Milestones</name>\n            <url>https://repo.spring.io/milestone</url>\n            <snapshots>\n                <enabled>false</enabled>\n            </snapshots>\n        </repository>\n    </repositories>\n\n    <pluginRepositories>\n        <pluginRepository>\n            <id>spring-snapshots</id>\n            <name>Spring Snapshots</name>\n            <url>https://repo.spring.io/snapshot</url>\n            <snapshots>\n                <enabled>true</enabled>\n            </snapshots>\n        </pluginRepository>\n        <pluginRepository>\n            <id>spring-milestones</id>\n            <name>Spring Milestones</name>\n            <url>https://repo.spring.io/milestone</url>\n            <snapshots>\n                <enabled>false</enabled>\n            </snapshots>\n        </pluginRepository>\n    </pluginRepositories>\n\n\n</project>\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/SqlToJavaApplication.java",
    "content": "package org.blackdread.sqltojava;\n\nimport java.util.List;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.entity.JdlEntity;\nimport org.blackdread.sqltojava.service.logic.ExportService;\nimport org.blackdread.sqltojava.service.logic.JdlService;\nimport org.blackdread.sqltojava.service.logic.SqlService;\nimport org.blackdread.sqltojava.util.AppUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.CommandLineRunner;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.boot.context.properties.EnableConfigurationProperties;\n\n@EnableConfigurationProperties(ApplicationProperties.class)\n@SpringBootApplication\npublic class SqlToJavaApplication implements CommandLineRunner {\n\n    private static final Logger log = LoggerFactory.getLogger(SqlToJavaApplication.class);\n\n    private final ApplicationProperties applicationProperties;\n\n    private final SqlService sqlService;\n\n    private final JdlService jdlService;\n\n    private final ExportService exportService;\n\n    public SqlToJavaApplication(\n        final ApplicationProperties applicationProperties,\n        final SqlService sqlService,\n        final JdlService jdlService,\n        final ExportService exportService\n    ) {\n        this.applicationProperties = applicationProperties;\n        this.sqlService = sqlService;\n        this.jdlService = jdlService;\n        this.exportService = exportService;\n    }\n\n    public static void main(String[] args) {\n        SpringApplication app = new SpringApplicationBuilder(SqlToJavaApplication.class).application();\n        AppUtil.setup(app).run(args);\n    }\n\n    @Override\n    public void run(final String... args) throws Exception {\n        log.warn(\"Arguments passed: {}\", args);\n        final List<JdlEntity> entities = jdlService.buildEntities();\n\n        exportService.export(entities);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/config/ApplicationProperties.java",
    "content": "package org.blackdread.sqltojava.config;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.stream.Collectors;\nimport org.blackdread.sqltojava.entity.JdlFieldEnum;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.boot.context.properties.ConstructorBinding;\nimport org.springframework.boot.json.JsonParserFactory;\nimport org.springframework.util.ResourceUtils;\n\n@ConstructorBinding\n@ConfigurationProperties(prefix = \"application\", ignoreUnknownFields = false)\npublic class ApplicationProperties {\n\n    private static final Logger log = LoggerFactory.getLogger(ApplicationProperties.class);\n\n    /**\n     * Database name to export to JDL\n     */\n    private final String databaseToExport;\n    private final List<String> databaseObjectPrefix;\n    private final boolean addTableNameJdl;\n    private final UndefinedJdlTypeHandlingEnum undefinedTypeHandling;\n    private final DatabaseObjectTypesConfigEnum databaseObjectTypesConfig;\n    private final Boolean renderEntitiesOnly;\n    private final Boolean assumeBidirectional;\n    private final List<String> ignoredTableNames;\n    private final Export export;\n    private final List<String> reservedList;\n    private final Map<String, JdlFieldEnum> jdlTypeOverrides;\n\n    @SuppressWarnings(\"unchecked\")\n    public ApplicationProperties(\n        final String databaseToExport,\n        final List<String> databaseObjectPrefix,\n        final Boolean addTableNameJdl,\n        final UndefinedJdlTypeHandlingEnum undefinedTypeHandling,\n        final DatabaseObjectTypesConfigEnum databaseObjectTypesConfig,\n        final Boolean renderEntitiesOnly,\n        final Boolean assumeBidirectional,\n        final List<String> ignoredTableNames,\n        final Export export,\n        final String reservedKeywords,\n        final Map<String, JdlFieldEnum> jdlTypeOverrides\n    ) {\n        log.info(\"Loading ApplicationProperties...\");\n        this.databaseToExport = databaseToExport;\n        this.databaseObjectPrefix = databaseObjectPrefix;\n        this.undefinedTypeHandling = undefinedTypeHandling;\n        this.databaseObjectTypesConfig = databaseObjectTypesConfig;\n        this.renderEntitiesOnly = renderEntitiesOnly;\n        this.assumeBidirectional = assumeBidirectional;\n        this.addTableNameJdl = Optional.of(addTableNameJdl).orElse(false);\n        this.ignoredTableNames = ignoredTableNames;\n        this.export = export;\n        this.reservedList =\n            JsonParserFactory\n                .getJsonParser()\n                .parseMap(keywordsAsJson(reservedKeywords))\n                .values()\n                .stream()\n                .map(obj -> (List<String>) obj)\n                .flatMap(Collection::stream)\n                .collect(Collectors.toList());\n        this.jdlTypeOverrides = Optional.ofNullable(jdlTypeOverrides).orElse(Collections.emptyMap());\n    }\n\n    public String getDatabaseToExport() {\n        return databaseToExport;\n    }\n\n    public List<String> getIgnoredTableNames() {\n        return ignoredTableNames;\n    }\n\n    public Export getExport() {\n        return export;\n    }\n\n    public List<String> getReservedList() {\n        return reservedList;\n    }\n\n    public Boolean getAddTableNameJdl() {\n        return addTableNameJdl;\n    }\n\n    public UndefinedJdlTypeHandlingEnum getUndefinedTypeHandling() {\n        return undefinedTypeHandling;\n    }\n\n    public DatabaseObjectTypesConfigEnum getDatabaseObjectTypesConfig() {\n        return databaseObjectTypesConfig;\n    }\n\n    public Boolean isRenderEntitiesOnly() {\n        return renderEntitiesOnly;\n    }\n\n    public Boolean isAssumeBidirectional() {\n        return assumeBidirectional;\n    }\n\n    public List<String> getDatabaseObjectPrefix() {\n        return databaseObjectPrefix;\n    }\n\n    public Map<String, JdlFieldEnum> getJdlTypeOverrides() {\n        return jdlTypeOverrides;\n    }\n\n    public static class Export {\n\n        private final Path path;\n\n        private final String type;\n        private final ExportFileStructureType exportFileStructureType;\n        private final String exportMustacheTemplateFilenameOptional;\n\n        public Export(\n            final Path path,\n            final String type,\n            ExportFileStructureType exportFileStructureType,\n            String exportMustacheTemplateFilenameOptional\n        ) {\n            this.path = path;\n            this.type = type;\n            this.exportFileStructureType = exportFileStructureType;\n            this.exportMustacheTemplateFilenameOptional = exportMustacheTemplateFilenameOptional;\n        }\n\n        public Path getPath() {\n            return path;\n        }\n\n        public String getType() {\n            return type;\n        }\n\n        public ExportFileStructureType getExportFileStructureType() {\n            return exportFileStructureType;\n        }\n\n        public String getExportMustacheTemplateFilenameOptional() {\n            return exportMustacheTemplateFilenameOptional;\n        }\n    }\n\n    private String keywordsAsJson(String file) {\n        try {\n            Path path = ResourceUtils.getFile(file).toPath();\n            return String.join(\" \", Files.readAllLines(path));\n        } catch (IOException e) {\n            return \"{\\\"key\\\": []}\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/config/CacheConfiguration.java",
    "content": "package org.blackdread.sqltojava.config;\n\nimport org.springframework.cache.CacheManager;\nimport org.springframework.cache.annotation.EnableCaching;\nimport org.springframework.cache.concurrent.ConcurrentMapCacheManager;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\n@EnableCaching\npublic class CacheConfiguration {\n\n    @Bean\n    public CacheManager cacheManager() {\n        return new ConcurrentMapCacheManager();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/config/DatabaseObjectTypesConfigEnum.java",
    "content": "package org.blackdread.sqltojava.config;\n\npublic enum DatabaseObjectTypesConfigEnum {\n    TABLES,\n    VIEWS,\n    ALL,\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/config/ExportFileStructureType.java",
    "content": "package org.blackdread.sqltojava.config;\n\npublic enum ExportFileStructureType {\n    SEPARATED(\"application\", \"Every entity, relationship are separated\"),\n    GROUPED_RELATIONS_SEPARATE_VIEWS(\n        \"application-grouped-relations-separate-views\",\n        \"Relations are grouped by type, views  are separated from entites after entites and relations declarations\"\n    ),\n    RELATIONS_BEFORE_VIEWS_SEPARATE_VIEWS(\n        \"application-entities-relations-views\",\n        \"Relations are after entities and before views, views  are separated from entites after entites and relations declarations\"\n    );\n\n    private final String exportMustacheTemplateFilename;\n    private final String comment;\n\n    ExportFileStructureType(String exportMustacheTemplateFilename, String comment) {\n        this.exportMustacheTemplateFilename = exportMustacheTemplateFilename;\n        this.comment = comment;\n    }\n\n    public String getExportMustacheTemplateFilename() {\n        return exportMustacheTemplateFilename;\n    }\n\n    public String getComment() {\n        return comment;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/config/UndefinedJdlTypeHandlingEnum.java",
    "content": "package org.blackdread.sqltojava.config;\n\n/**\n * Determines how undefined SQL column types ar handled\n */\npublic enum UndefinedJdlTypeHandlingEnum {\n    /**\n     * Throw an error\n     */\n    ERROR,\n\n    /**\n     * Skip writing the field to JDL\n     */\n    SKIP,\n\n    /**\n     * Write Unsupported as type and require manual cleanup\n     */\n    UNSUPPORTED,\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/JdlEntity.java",
    "content": "package org.blackdread.sqltojava.entity;\n\nimport java.util.List;\nimport java.util.Optional;\n\npublic interface JdlEntity {\n    String getName();\n\n    String getTableName();\n\n    List<JdlField> getFields();\n\n    /**\n     * Add @readOnly to read only entity.\n     * https://www.jhipster.tech/jdl/options\n     */\n    boolean isReadOnly();\n\n    Optional<String> getComment();\n\n    boolean isEnumEntity();\n\n    /**\n     * A pure ManyToMany entity only contains 2 columns of foreign keys\n     *\n     * @return True if this entity represent a pure ManyToMany relation of two other entities\n     */\n    boolean isPureManyToMany();\n\n    /**\n     * @return Relations where this entity is the owner side\n     */\n    List<JdlRelation> getRelations();\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/JdlField.java",
    "content": "package org.blackdread.sqltojava.entity;\n\nimport java.util.Optional;\n\npublic interface JdlField {\n    JdlFieldEnum getType();\n\n    String getName();\n\n    /**\n     * @return Entity name of the enum if this field is an enum value\n     */\n    Optional<String> getEnumEntityName();\n\n    /**\n     * Some DB support native enum (no use of extra table as an enum).\n     * If is true then {@link #getEnumEntityName()} is not empty.\n     *\n     * @return true if field was created from a native enum column\n     */\n    boolean isNativeEnum();\n\n    boolean isRequired();\n\n    Optional<String> getComment();\n\n    /**\n     * Min of field (represent minLength if is a string)\n     *\n     * @return Min value of field\n     */\n    Optional<Integer> getMin();\n\n    /**\n     * Max of field (represent miaxength if is a string)\n     *\n     * @return Max value of field\n     */\n    Optional<Integer> getMax();\n\n    Optional<String> getPattern();\n\n    /**\n     * @return - <code>true</code> if the column is marked as a unique column\n     */\n    boolean isUnique();\n\n    /**\n     * @return - <code>true</code> if the column is marked as a primary key column\n     */\n    boolean isPrimaryKey();\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/JdlFieldEnum.java",
    "content": "package org.blackdread.sqltojava.entity;\n\nimport com.google.common.base.CaseFormat;\n\npublic enum JdlFieldEnum {\n    STRING,\n    INTEGER,\n    LONG,\n    BIG_DECIMAL,\n    FLOAT,\n    DOUBLE,\n    ENUM,\n    BOOLEAN,\n    LOCAL_DATE,\n    ZONED_DATE_TIME,\n    INSTANT,\n    BLOB,\n    ANY_BLOB,\n    IMAGE_BLOB,\n    TEXT_BLOB,\n\n    /**\n     * Used for native enums from DBs, values are defined in the DB so can be extracted.\n     *\n     * @deprecated not sure yet, this should be checked via extra methods and not a type\n     */\n    ENUM_NATIVE,\n\n    /**\n     * Defined here to allow to have a pattern set for TIME type of SQL that jdl does not support by default\n     */\n    TIME_AS_TEXT,\n    /**\n     * Defined here to allow to have a pattern set for YEAR type of SQL that jdl does not support by default\n     */\n    YEAR_AS_TEXT,\n    /**\n     * Defined here to allow to have a pattern set for GEOMETRY type of SQL that jdl does not support by default\n     */\n    GEOMETRY_AS_TEXT,\n    /**\n     * Defined here to allow to have a string without max length set for json type of SQL that jdl does not support by default\n     */\n    JSON_AS_TEXT,\n\n    UUID,\n\n    /**\n     * Defined here to allow to have a string without max length set for postgres text type\n     */\n    STRING_UNBOUNDED,\n\n    /**\n     * Defined here to allow to jdl to generate with unsupported fields rather than failing with an error.\n     */\n    UNSUPPORTED;\n\n    public String toCamelUpper() {\n        return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, this.name());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/JdlRelation.java",
    "content": "package org.blackdread.sqltojava.entity;\n\nimport java.util.Optional;\n\npublic interface JdlRelation {\n    RelationType getRelationType();\n\n    boolean isBidirectional();\n\n    boolean isOwnerRequired();\n\n    boolean isInverseSideRequired();\n\n    //    boolean isMapsId();\n\n    Optional<String> getOwnerComment();\n\n    Optional<String> getInverseSideComment();\n\n    /**\n     * A comment that can be set to be displayed on top of the relation declaration, to help review the generated\n     *\n     * @return an extra comment\n     */\n    Optional<String> getComment();\n\n    /**\n     * OwnerSideEntityName{ownerRelationName(ownerDisplayField) required} to InverseSideEntityName{inverseSideRelationName(inverseSideDisplayField)}\n     *\n     * @return Entity name of owner side\n     */\n    String getOwnerEntityName();\n\n    /**\n     * OwnerSideEntityName{ownerRelationName(ownerDisplayField) required} to InverseSideEntityName{inverseSideRelationName(inverseSideDisplayField)}\n     *\n     * @return Entity name of inverse side\n     */\n    String getInverseSideEntityName();\n\n    /**\n     * @return Represent the \"relationship name\" on the owner side\n     */\n    String getOwnerRelationName();\n\n    /**\n     * OwnerSideEntityName{ownerRelationName(ownerDisplayField) required} to InverseSideEntityName{inverseSideRelationName(inverseSideDisplayField)}\n     *\n     * @return Represent the \"relationship name\" on the inverse side\n     */\n    Optional<String> getInverseSideRelationName();\n\n    /**\n     * OwnerSideEntityName{ownerRelationName(ownerDisplayField) required} to InverseSideEntityName{inverseSideRelationName(inverseSideDisplayField)}\n     *\n     * @return Represent the \"display field name\" on the owner side\n     */\n    Optional<String> getOwnerDisplayField();\n\n    /**\n     * OwnerSideEntityName{ownerRelationName(ownerDisplayField) required} to InverseSideEntityName{inverseSideRelationName(inverseSideDisplayField)}\n     *\n     * @return Represent the \"display field name\" on the inverse side\n     */\n    Optional<String> getInverseSideDisplayField();\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/JdlRelationGroup.java",
    "content": "package org.blackdread.sqltojava.entity;\n\nimport java.util.List;\n\npublic interface JdlRelationGroup {\n    RelationType getRelationType();\n    List<JdlRelation> getRelations();\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/RelationType.java",
    "content": "package org.blackdread.sqltojava.entity;\n\npublic enum RelationType {\n    /**\n     * @deprecated no reason to keep that, exception way before should happen\n     */\n    @Deprecated\n    Unknown,\n    /**\n     * E.g: Can be known if sql column is unique\n     */\n    OneToOne,\n    ManyToOne,\n    ManyToMany;\n\n    // OneToMany is not put as we always use ManyToOne\n\n    public String toJdl() {\n        return this.name();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/SqlColumn.java",
    "content": "package org.blackdread.sqltojava.entity;\n\nimport java.util.Optional;\n\npublic interface SqlColumn {\n    SqlTable getTable();\n\n    /**\n     * @return Column name\n     */\n    String getName();\n\n    /**\n     * Is usually a value of type and size like \"type(size)\"\n     *\n     * @return Column type\n     */\n    String getType();\n\n    boolean isPrimaryKey();\n\n    boolean isForeignKey();\n\n    boolean isNullable();\n\n    boolean isUnique();\n\n    /**\n     * Some DB support native enum (no use of extra table as an enum)\n     *\n     * @return true if column is a native enum\n     */\n    boolean isNativeEnum();\n\n    Optional<String> getDefaultValue();\n\n    Optional<String> getComment();\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/SqlForeignKey.java",
    "content": "package org.blackdread.sqltojava.entity;\n\npublic interface SqlForeignKey {}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/SqlTable.java",
    "content": "package org.blackdread.sqltojava.entity;\n\nimport java.util.Optional;\n\npublic interface SqlTable {\n    String getName();\n    Optional<String> getComment();\n    boolean isUpdatable();\n    String getType();\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/JdlEntityImpl.java",
    "content": "package org.blackdread.sqltojava.entity.impl;\n\nimport com.google.common.collect.ImmutableList;\nimport java.util.List;\nimport java.util.Optional;\nimport javax.annotation.Nullable;\nimport javax.annotation.concurrent.Immutable;\nimport javax.annotation.concurrent.ThreadSafe;\nimport org.apache.commons.lang3.StringUtils;\nimport org.blackdread.sqltojava.entity.JdlEntity;\nimport org.blackdread.sqltojava.entity.JdlField;\nimport org.blackdread.sqltojava.entity.JdlRelation;\n\n@Immutable\n@ThreadSafe\npublic class JdlEntityImpl implements JdlEntity, Comparable<JdlEntity> {\n\n    private final String name;\n\n    private final String tableName;\n\n    private final List<JdlField> fields;\n\n    private final String comment;\n\n    private final boolean readOnly;\n\n    private final boolean enumEntity;\n\n    private final boolean pureManyToMany;\n\n    private final List<JdlRelation> relations;\n\n    public JdlEntityImpl(\n        final String name,\n        final String tableName,\n        final List<JdlField> fields,\n        @Nullable final String comment,\n        final boolean enumEntity,\n        final boolean readOnly,\n        final boolean pureManyToMany,\n        final List<JdlRelation> relations\n    ) {\n        this.name = name;\n        this.tableName = tableName;\n        this.fields = ImmutableList.copyOf(fields);\n        this.comment = (StringUtils.isBlank(comment) || \"null\".equalsIgnoreCase(comment)) ? null : comment;\n        this.enumEntity = enumEntity;\n        this.readOnly = readOnly;\n        this.pureManyToMany = pureManyToMany;\n        this.relations = ImmutableList.copyOf(relations);\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public String getTableName() {\n        return tableName;\n    }\n\n    @Override\n    public List<JdlField> getFields() {\n        return fields;\n    }\n\n    @Override\n    public Optional<String> getComment() {\n        return Optional.ofNullable(comment);\n    }\n\n    @Override\n    public boolean isEnumEntity() {\n        return enumEntity;\n    }\n\n    @Override\n    public boolean isReadOnly() {\n        return readOnly;\n    }\n\n    @Override\n    public boolean isPureManyToMany() {\n        return pureManyToMany;\n    }\n\n    @Override\n    public List<JdlRelation> getRelations() {\n        return relations;\n    }\n\n    @Override\n    public String toString() {\n        return (\n            \"JdlEntityImpl{\" +\n            \"name='\" +\n            name +\n            '\\'' +\n            \"tableName='\" +\n            tableName +\n            '\\'' +\n            \", fields=\" +\n            fields +\n            \", comment='\" +\n            comment +\n            '\\'' +\n            \", readOnly=\" +\n            readOnly +\n            \", isEnum=\" +\n            enumEntity +\n            \", relations=\" +\n            relations +\n            '}'\n        );\n    }\n\n    @Override\n    public int compareTo(final JdlEntity o) {\n        return name.compareTo(o.getName());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/JdlFieldImpl.java",
    "content": "package org.blackdread.sqltojava.entity.impl;\n\nimport java.util.Optional;\nimport javax.annotation.Nullable;\nimport javax.annotation.concurrent.Immutable;\nimport javax.annotation.concurrent.ThreadSafe;\nimport org.apache.commons.lang3.StringUtils;\nimport org.blackdread.sqltojava.entity.JdlField;\nimport org.blackdread.sqltojava.entity.JdlFieldEnum;\n\n@Immutable\n@ThreadSafe\npublic class JdlFieldImpl implements JdlField {\n\n    private final JdlFieldEnum type;\n    private final String name;\n    private final String enumEntityName;\n    private final boolean required;\n    private final String comment;\n    private final Integer min;\n    private final Integer max;\n    private final String pattern;\n    private final Boolean nativeEnum;\n    private final Boolean unique;\n    private final Boolean primaryKey;\n\n    public JdlFieldImpl(\n        final JdlFieldEnum type,\n        final String name,\n        final boolean required,\n        @Nullable final String comment,\n        @Nullable final Integer min,\n        @Nullable final Integer max,\n        @Nullable final String pattern,\n        @Nullable final String enumEntityName,\n        final boolean nativeEnum,\n        final boolean unique,\n        final boolean primaryKey\n    ) {\n        this.type = type;\n        this.name = name;\n        this.required = required;\n        this.comment = (StringUtils.isBlank(comment) || \"null\".equalsIgnoreCase(comment)) ? null : comment;\n        this.min = min;\n        this.max = max;\n        this.pattern = pattern;\n        this.enumEntityName = enumEntityName;\n        this.nativeEnum = nativeEnum;\n        this.unique = unique;\n        this.primaryKey = primaryKey;\n    }\n\n    @Override\n    public JdlFieldEnum getType() {\n        return type;\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public Optional<String> getEnumEntityName() {\n        return Optional.ofNullable(enumEntityName);\n    }\n\n    @Override\n    public boolean isRequired() {\n        return required;\n    }\n\n    @Override\n    public Optional<String> getComment() {\n        return Optional.ofNullable(comment);\n    }\n\n    @Override\n    public Optional<Integer> getMin() {\n        return Optional.ofNullable(min);\n    }\n\n    @Override\n    public Optional<Integer> getMax() {\n        return Optional.ofNullable(max);\n    }\n\n    @Override\n    public Optional<String> getPattern() {\n        return Optional.ofNullable(pattern);\n    }\n\n    @Override\n    public boolean isUnique() {\n        return unique;\n    }\n\n    @Override\n    public boolean isPrimaryKey() {\n        return primaryKey;\n    }\n\n    @Override\n    public boolean isNativeEnum() {\n        return nativeEnum;\n    }\n\n    @Override\n    public String toString() {\n        return (\n            \"JdlFieldImpl{\" +\n            \"type=\" +\n            type +\n            \", name='\" +\n            name +\n            '\\'' +\n            \", enumEntityName='\" +\n            enumEntityName +\n            '\\'' +\n            \", isRequired=\" +\n            required +\n            \", comment='\" +\n            comment +\n            '\\'' +\n            \", min=\" +\n            min +\n            \", max=\" +\n            max +\n            \", pattern='\" +\n            pattern +\n            '\\'' +\n            \", isNativeEnum=\" +\n            nativeEnum +\n            '}'\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/JdlRelationGroupImpl.java",
    "content": "package org.blackdread.sqltojava.entity.impl;\n\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.stream.Collectors;\nimport javax.annotation.concurrent.Immutable;\nimport javax.annotation.concurrent.ThreadSafe;\nimport org.blackdread.sqltojava.entity.JdlRelation;\nimport org.blackdread.sqltojava.entity.JdlRelationGroup;\nimport org.blackdread.sqltojava.entity.RelationType;\n\n@Immutable\n@ThreadSafe\npublic class JdlRelationGroupImpl implements JdlRelationGroup, Comparable<JdlRelationGroup> {\n\n    private final RelationType relationType;\n    private final List<JdlRelation> relations;\n\n    public JdlRelationGroupImpl(RelationType relationType, List<JdlRelation> relations) {\n        this.relationType = relationType;\n        this.relations = relations;\n    }\n\n    public RelationType getRelationType() {\n        return relationType;\n    }\n\n    public List<JdlRelation> getRelations() {\n        return relations;\n    }\n\n    @Override\n    public int compareTo(final JdlRelationGroup o) {\n        return this.relationType.compareTo(o.getRelationType());\n    }\n\n    @Override\n    public String toString() {\n        return (\n            \"JdlRelationGroupImpl{\" +\n            \"relationType=\" +\n            relationType +\n            \", relations=\" +\n            relations.stream().map(e -> e.getOwnerEntityName()).collect(Collectors.joining()) +\n            '}'\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/JdlRelationImpl.java",
    "content": "package org.blackdread.sqltojava.entity.impl;\n\nimport java.util.Optional;\nimport javax.annotation.Nullable;\nimport javax.annotation.concurrent.Immutable;\nimport javax.annotation.concurrent.ThreadSafe;\nimport org.apache.commons.lang3.StringUtils;\nimport org.blackdread.sqltojava.entity.JdlRelation;\nimport org.blackdread.sqltojava.entity.RelationType;\n\n@Immutable\n@ThreadSafe\npublic class JdlRelationImpl implements JdlRelation, Comparable<JdlRelation> {\n\n    private final RelationType relationType;\n\n    private final boolean bidirectional;\n    private final boolean ownerRequired;\n    private final boolean inverseSideRequired;\n\n    private final String ownerEntityName;\n    private final String inverseSideEntityName;\n\n    private final String ownerRelationName;\n    private final String ownerDisplayField;\n\n    private final String ownerComment;\n    private final String inverseSideComment;\n    private final String inverseSideRelationName;\n    private final String inverseSideDisplayField;\n\n    private final String comment;\n\n    public JdlRelationImpl(\n        final RelationType relationType,\n        final boolean bidirectional,\n        final boolean ownerRequired,\n        final boolean inverseSideRequired,\n        final String ownerEntityName,\n        final String inverseSideEntityName,\n        final String ownerRelationName,\n        @Nullable final String ownerDisplayField,\n        @Nullable final String ownerComment,\n        @Nullable final String inverseSideComment,\n        @Nullable final String inverseSideRelationName,\n        @Nullable final String inverseSideDisplayField,\n        @Nullable final String comment\n    ) {\n        this.relationType = relationType;\n        this.bidirectional = bidirectional;\n        this.ownerRequired = ownerRequired;\n        this.inverseSideRequired = inverseSideRequired;\n\n        this.ownerEntityName = ownerEntityName;\n        this.inverseSideEntityName = inverseSideEntityName;\n\n        this.ownerRelationName = ownerRelationName;\n        this.ownerDisplayField =\n            (StringUtils.isBlank(ownerDisplayField) || \"null\".equalsIgnoreCase(ownerDisplayField)) ? null : ownerDisplayField;\n\n        this.ownerComment = (StringUtils.isBlank(ownerComment) || \"null\".equalsIgnoreCase(ownerComment)) ? null : ownerComment;\n        this.inverseSideComment =\n            (StringUtils.isBlank(inverseSideComment) || \"null\".equalsIgnoreCase(inverseSideComment)) ? null : inverseSideComment;\n        this.inverseSideRelationName =\n            (StringUtils.isBlank(inverseSideRelationName) || \"null\".equalsIgnoreCase(inverseSideRelationName))\n                ? null\n                : inverseSideRelationName;\n        this.inverseSideDisplayField =\n            (StringUtils.isBlank(inverseSideDisplayField) || \"null\".equalsIgnoreCase(inverseSideDisplayField))\n                ? null\n                : inverseSideDisplayField;\n        this.comment = (StringUtils.isBlank(comment) || \"null\".equalsIgnoreCase(comment)) ? null : comment;\n    }\n\n    @Override\n    public RelationType getRelationType() {\n        return relationType;\n    }\n\n    @Override\n    public boolean isBidirectional() {\n        return bidirectional;\n    }\n\n    @Override\n    public boolean isOwnerRequired() {\n        return ownerRequired;\n    }\n\n    @Override\n    public boolean isInverseSideRequired() {\n        return inverseSideRequired;\n    }\n\n    @Override\n    public Optional<String> getOwnerComment() {\n        return Optional.ofNullable(ownerComment);\n    }\n\n    @Override\n    public Optional<String> getInverseSideComment() {\n        return Optional.ofNullable(inverseSideComment);\n    }\n\n    @Override\n    public Optional<String> getComment() {\n        return Optional.ofNullable(comment);\n    }\n\n    @Override\n    public String getOwnerEntityName() {\n        return ownerEntityName;\n    }\n\n    @Override\n    public String getInverseSideEntityName() {\n        return inverseSideEntityName;\n    }\n\n    @Override\n    public String getOwnerRelationName() {\n        return ownerRelationName;\n    }\n\n    @Override\n    public Optional<String> getInverseSideRelationName() {\n        return Optional.ofNullable(inverseSideRelationName);\n    }\n\n    @Override\n    public Optional<String> getOwnerDisplayField() {\n        return Optional.ofNullable(ownerDisplayField);\n    }\n\n    @Override\n    public Optional<String> getInverseSideDisplayField() {\n        return Optional.ofNullable(inverseSideDisplayField);\n    }\n\n    @Override\n    public int compareTo(final JdlRelation o) {\n        return this.ownerEntityName.compareTo(o.getOwnerEntityName());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/SqlColumnImpl.java",
    "content": "package org.blackdread.sqltojava.entity.impl;\n\nimport java.util.Objects;\nimport java.util.Optional;\nimport javax.annotation.Nullable;\nimport org.apache.commons.lang3.StringUtils;\nimport org.blackdread.sqltojava.entity.SqlColumn;\nimport org.blackdread.sqltojava.entity.SqlTable;\n\npublic class SqlColumnImpl implements SqlColumn {\n\n    private final SqlTable table;\n\n    private final String name;\n\n    private final String type;\n\n    private final boolean isPrimaryKey;\n\n    private final boolean isForeignKey;\n\n    private final boolean isNullable;\n\n    private final boolean isUnique;\n\n    private final boolean isNativeEnum;\n\n    private final String defaultValue;\n\n    private final String comment;\n\n    public SqlColumnImpl(\n        final SqlTable table,\n        final String name,\n        final String type,\n        final boolean isPrimaryKey,\n        final boolean isForeignKey,\n        final boolean isNullable,\n        final boolean isUnique,\n        final boolean isNativeEnum,\n        @Nullable final String defaultValue,\n        final String comment\n    ) {\n        this.table = table;\n        this.name = name;\n        this.type = type;\n        this.isPrimaryKey = isPrimaryKey;\n        this.isForeignKey = isForeignKey;\n        this.isNullable = isNullable;\n        this.isUnique = isUnique;\n        this.isNativeEnum = isNativeEnum;\n        this.defaultValue = (StringUtils.isBlank(defaultValue) || \"null\".equalsIgnoreCase(comment)) ? null : defaultValue;\n        this.comment = (StringUtils.isBlank(comment) || \"null\".equalsIgnoreCase(comment)) ? null : comment;\n    }\n\n    @Override\n    public SqlTable getTable() {\n        return table;\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public String getType() {\n        return type;\n    }\n\n    @Override\n    public boolean isPrimaryKey() {\n        return isPrimaryKey;\n    }\n\n    @Override\n    public boolean isForeignKey() {\n        return isForeignKey;\n    }\n\n    @Override\n    public boolean isNullable() {\n        return isNullable;\n    }\n\n    @Override\n    public boolean isUnique() {\n        return isUnique;\n    }\n\n    @Override\n    public boolean isNativeEnum() {\n        return isNativeEnum;\n    }\n\n    @Override\n    public Optional<String> getDefaultValue() {\n        return Optional.ofNullable(defaultValue);\n    }\n\n    @Override\n    public Optional<String> getComment() {\n        return Optional.ofNullable(comment);\n    }\n\n    @Override\n    public boolean equals(final Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n        final SqlColumnImpl sqlColumn = (SqlColumnImpl) o;\n        return (Objects.equals(table, sqlColumn.table) && Objects.equals(name, sqlColumn.name) && Objects.equals(type, sqlColumn.type));\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(table, name, type);\n    }\n\n    @Override\n    public String toString() {\n        return (\n            \"SqlColumnImpl{\" +\n            \"table=\" +\n            table +\n            \", name='\" +\n            name +\n            '\\'' +\n            \", type='\" +\n            type +\n            '\\'' +\n            \", isPrimaryKey=\" +\n            isPrimaryKey +\n            \", isForeignKey=\" +\n            isForeignKey +\n            \", isNullable=\" +\n            isNullable +\n            \", isUnique=\" +\n            isUnique +\n            \", isNativeEnum=\" +\n            isNativeEnum +\n            \", defaultValue='\" +\n            defaultValue +\n            '\\'' +\n            \", comment='\" +\n            comment +\n            '\\'' +\n            '}'\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/SqlTableImpl.java",
    "content": "package org.blackdread.sqltojava.entity.impl;\n\nimport java.util.Objects;\nimport java.util.Optional;\nimport javax.annotation.Nullable;\nimport org.apache.commons.lang3.StringUtils;\nimport org.blackdread.sqltojava.entity.SqlTable;\n\npublic class SqlTableImpl implements SqlTable, Comparable<SqlTable> {\n\n    private final String name;\n    private final String comment;\n    private final boolean isUpdateable;\n    private final String type;\n\n    public SqlTableImpl(final String name, @Nullable final String comment, final String type, final boolean isUpdateable) {\n        this.name = Objects.requireNonNull(name);\n        this.comment = (StringUtils.isBlank(comment) || \"null\".equalsIgnoreCase(comment)) ? null : comment;\n        this.type = type;\n        this.isUpdateable = isUpdateable;\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public Optional<String> getComment() {\n        return Optional.ofNullable(comment);\n    }\n\n    @Override\n    public String getType() {\n        return type;\n    }\n\n    @Override\n    public boolean isUpdatable() {\n        return isUpdateable;\n    }\n\n    @Override\n    public boolean equals(final Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n        final SqlTableImpl sqlTable = (SqlTableImpl) o;\n        return Objects.equals(name, sqlTable.name);\n    }\n\n    @Override\n    public int hashCode() {\n        return name.hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return (\"SqlTableImpl{\" + \"name='\" + name + '\\'' + \", comment='\" + comment + '\\'' + '}');\n    }\n\n    @Override\n    public int compareTo(final SqlTable o) {\n        return name.compareTo(o.getName());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/exporter/ExportFileStructureConfig.java",
    "content": "package org.blackdread.sqltojava.exporter;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.config.ExportFileStructureType;\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class ExportFileStructureConfig {\n\n    private final ApplicationProperties applicationProperties;\n    private ExportFileStructureType exportFileStructureType;\n    private String exportMustacheTemplateFilename;\n\n    public ExportFileStructureConfig(ApplicationProperties applicationProperties) {\n        this.applicationProperties = applicationProperties;\n        exportFileStructureType = applicationProperties.getExport().getExportFileStructureType();\n        String newTemplateName = applicationProperties.getExport().getExportMustacheTemplateFilenameOptional();\n        exportMustacheTemplateFilename =\n            StringUtils.isBlank(newTemplateName) ? exportFileStructureType.getExportMustacheTemplateFilename() : newTemplateName;\n    }\n\n    public String getExportMustacheTemplateFilename() {\n        return exportMustacheTemplateFilename;\n    }\n\n    public ExportFileStructureType getExportFileStructureType() {\n        return exportFileStructureType;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/listener/SetDatabaseProfileApplicationEventListener.java",
    "content": "package org.blackdread.sqltojava.listener;\n\nimport org.blackdread.sqltojava.util.JdbcUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;\nimport org.springframework.context.ApplicationListener;\nimport org.springframework.core.env.ConfigurableEnvironment;\n\npublic class SetDatabaseProfileApplicationEventListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {\n\n    private static final Logger log = LoggerFactory.getLogger(SetDatabaseProfileApplicationEventListener.class);\n\n    @Override\n    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent e) {\n        ConfigurableEnvironment env = e.getEnvironment();\n        String[] activeProfiles = env.getActiveProfiles();\n\n        if (activeProfiles.length == 0) {\n            String jdbcUrl = env.getProperty(\"spring.datasource.url\");\n            String profileName = JdbcUtil.getDatabaseTypeFromJdbcUrl(jdbcUrl);\n            log.debug(String.format(\"No active profiles using %s from %s\", profileName, jdbcUrl));\n            env.setActiveProfiles(profileName);\n        } else {\n            log.debug(String.format(\"Active profile %s found.  Automatic setting from spring.datasource.url disabled.\", activeProfiles));\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/parser/SqlParser.java",
    "content": "package org.blackdread.sqltojava.parser;\n\nimport com.google.common.io.Files;\nimport java.io.File;\n\npublic class SqlParser {\n\n    /**\n     * @param fileToParse Sql file\n     * @param saveInto    Jdl file to save into\n     */\n    public static void parse(final File fileToParse, final File saveInto) {\n        checkIsSql(fileToParse);\n    }\n\n    private static void checkIsSql(final File file) {\n        final String fileExtension = Files.getFileExtension(file.getName());\n        if (!fileExtension.equalsIgnoreCase(\"sql\")) {\n            throw new IllegalArgumentException(\"Not an sql file\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/ColumnInformation.java",
    "content": "package org.blackdread.sqltojava.pojo;\n\nimport java.util.Optional;\nimport org.apache.commons.lang3.StringUtils;\n\npublic class ColumnInformation {\n\n    private final String name;\n    private final String type;\n    private final boolean isNullable;\n    private final boolean isPrimary;\n    private final boolean isUnique;\n    private final String defaultValue;\n    private final int ordinalPosition;\n    private final String comment;\n\n    public ColumnInformation(\n        final String name,\n        final String type,\n        final boolean isNullable,\n        final boolean isPrimary,\n        final boolean isUnique,\n        final String defaultValue,\n        final int ordinalPosition,\n        final String comment\n    ) {\n        this.name = name;\n        this.type = type;\n        this.isNullable = isNullable;\n        this.isPrimary = isPrimary;\n        this.isUnique = isUnique;\n        if (StringUtils.isBlank(defaultValue) || \"null\".equalsIgnoreCase(defaultValue)) {\n            this.defaultValue = null;\n        } else {\n            this.defaultValue = defaultValue;\n        }\n        this.ordinalPosition = ordinalPosition;\n        this.comment = comment;\n    }\n\n    public ColumnInformation(\n        final String name,\n        final String type,\n        final String nullValue,\n        final String keyValue,\n        final String defaultValue,\n        int ordinalPosition,\n        final String comment\n    ) {\n        this(\n            name,\n            type,\n            \"yes\".equalsIgnoreCase(nullValue),\n            \"pri\".equalsIgnoreCase(keyValue),\n            \"uni\".equalsIgnoreCase(keyValue),\n            defaultValue,\n            ordinalPosition,\n            comment\n        );\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public String getType() {\n        return type;\n    }\n\n    public boolean isNullable() {\n        return isNullable;\n    }\n\n    public boolean isPrimary() {\n        return isPrimary;\n    }\n\n    public boolean isUnique() {\n        return isUnique;\n    }\n\n    public Optional<String> getDefaultValue() {\n        return Optional.ofNullable(defaultValue);\n    }\n\n    public int getOrdinalPosition() {\n        return ordinalPosition;\n    }\n\n    public String getComment() {\n        return comment;\n    }\n\n    @Override\n    public String toString() {\n        return (\n            \"ColumnInformation{\" +\n            \"name='\" +\n            name +\n            '\\'' +\n            \", type='\" +\n            type +\n            '\\'' +\n            \", isNullable=\" +\n            isNullable +\n            \", isPrimary=\" +\n            isPrimary +\n            \", isUnique=\" +\n            isUnique +\n            \", defaultValue='\" +\n            defaultValue +\n            '\\'' +\n            \", comment='\" +\n            comment +\n            '\\'' +\n            '}'\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/TableInformation.java",
    "content": "package org.blackdread.sqltojava.pojo;\n\nimport java.util.Objects;\nimport java.util.Optional;\nimport org.apache.commons.lang3.StringUtils;\n\npublic class TableInformation {\n\n    private String schema;\n    private final String name;\n    private final String comment;\n    private final boolean isUpdateable;\n    private final String type;\n\n    public TableInformation(final String name, final boolean isUpdateable, String type, final String comment) {\n        this.name = name;\n        this.isUpdateable = isUpdateable;\n        this.comment = (StringUtils.isBlank(comment) || \"null\".equalsIgnoreCase(comment)) ? null : comment;\n        this.type = type;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public Optional<String> getComment() {\n        return Optional.ofNullable(comment);\n    }\n\n    public String getSchema() {\n        return schema;\n    }\n\n    public Boolean isUpdateable() {\n        return isUpdateable;\n    }\n\n    public String getType() {\n        return type;\n    }\n\n    @Override\n    public String toString() {\n        return (\"TableInformation{\" + \"name='\" + name + '\\'' + \", comment='\" + comment + '\\'' + '}');\n    }\n\n    @Override\n    public boolean equals(final Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n        final TableInformation that = (TableInformation) o;\n        return Objects.equals(name, that.name);\n    }\n\n    @Override\n    public int hashCode() {\n        return name.hashCode();\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/TableRelationInformation.java",
    "content": "package org.blackdread.sqltojava.pojo;\n\nimport java.util.Objects;\n\npublic class TableRelationInformation {\n\n    private final String tableName;\n    private final String columnName;\n    private final String referencedTableName;\n    private final String referencedColumnName;\n\n    public TableRelationInformation(\n        final String tableName,\n        final String columnName,\n        final String referencedTableName,\n        final String referencedColumnName\n    ) {\n        this.tableName = tableName;\n        this.columnName = columnName;\n        this.referencedTableName = referencedTableName;\n        this.referencedColumnName = referencedColumnName;\n    }\n\n    public String getTableName() {\n        return tableName;\n    }\n\n    public String getColumnName() {\n        return columnName;\n    }\n\n    public String getReferencedTableName() {\n        return referencedTableName;\n    }\n\n    public String getReferencedColumnName() {\n        return referencedColumnName;\n    }\n\n    @Override\n    public boolean equals(final Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n        final TableRelationInformation that = (TableRelationInformation) o;\n        return (\n            Objects.equals(tableName, that.tableName) &&\n            Objects.equals(columnName, that.columnName) &&\n            Objects.equals(referencedTableName, that.referencedTableName) &&\n            Objects.equals(referencedColumnName, that.referencedColumnName)\n        );\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(tableName, columnName, referencedTableName, referencedColumnName);\n    }\n\n    @Override\n    public String toString() {\n        return (\n            \"TableRelationInformation{\" +\n            \"tableName='\" +\n            tableName +\n            '\\'' +\n            \", columnName='\" +\n            columnName +\n            '\\'' +\n            \", referencedTableName='\" +\n            referencedTableName +\n            '\\'' +\n            \", referencedColumnName='\" +\n            referencedColumnName +\n            '\\'' +\n            '}'\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/rowmaper/ColumnInformationRowMapper.java",
    "content": "package org.blackdread.sqltojava.pojo.rowmaper;\n\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport org.blackdread.sqltojava.pojo.ColumnInformation;\nimport org.springframework.jdbc.core.RowMapper;\n\npublic class ColumnInformationRowMapper implements RowMapper<ColumnInformation> {\n\n    @Override\n    public ColumnInformation mapRow(ResultSet rs, int rowNum) throws SQLException {\n        return new ColumnInformation(\n            rs.getString(\"column_name\"),\n            rs.getString(\"data_type\"),\n            rs.getString(\"is_nullable\"),\n            rs.getString(\"key\"),\n            rs.getString(\"column_default\"),\n            rs.getInt(\"ordinal_position\"),\n            rs.getString(\"comment\")\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/rowmaper/SqlServerColumnInformationRowMapper.java",
    "content": "package org.blackdread.sqltojava.pojo.rowmaper;\n\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport org.blackdread.sqltojava.pojo.ColumnInformation;\nimport org.springframework.jdbc.core.RowMapper;\n\npublic class SqlServerColumnInformationRowMapper implements RowMapper<ColumnInformation> {\n\n    @Override\n    public ColumnInformation mapRow(ResultSet rs, int rowNum) throws SQLException {\n        return new ColumnInformation(\n            rs.getString(\"column_name\"),\n            rs.getString(\"data_type\"),\n            rs.getString(\"is_nullable\"),\n            rs.getString(\"keye\"),\n            rs.getString(\"column_default\"),\n            rs.getInt(\"ordinal_position\"),\n            \"\"\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/rowmaper/SqlServerTableInformationRowMapper.java",
    "content": "package org.blackdread.sqltojava.pojo.rowmaper;\n\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport org.blackdread.sqltojava.pojo.TableInformation;\nimport org.springframework.jdbc.core.RowMapper;\n\npublic class SqlServerTableInformationRowMapper implements RowMapper<TableInformation> {\n\n    @Override\n    public TableInformation mapRow(ResultSet rs, int rowNum) throws SQLException {\n        return new TableInformation(\n            rs.getString(\"table_name\"),\n            rs.getBoolean(\"updateable\"),\n            rs.getString(\"table_type\"),\n            rs.getString(\"comment\")\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/rowmaper/TableInformationRowMapper.java",
    "content": "package org.blackdread.sqltojava.pojo.rowmaper;\n\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport org.blackdread.sqltojava.pojo.TableInformation;\nimport org.springframework.jdbc.core.RowMapper;\n\npublic class TableInformationRowMapper implements RowMapper<TableInformation> {\n\n    @Override\n    public TableInformation mapRow(ResultSet rs, int rowNum) throws SQLException {\n        return new TableInformation(\n            rs.getString(\"table_name\"),\n            rs.getBoolean(\"is_updatable\"),\n            rs.getString(\"table_type\"),\n            rs.getString(\"comment\")\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/rowmaper/TableRelationInformationRowMapper.java",
    "content": "package org.blackdread.sqltojava.pojo.rowmaper;\n\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport org.blackdread.sqltojava.pojo.TableRelationInformation;\nimport org.springframework.jdbc.core.RowMapper;\n\npublic class TableRelationInformationRowMapper implements RowMapper<TableRelationInformation> {\n\n    @Override\n    public TableRelationInformation mapRow(ResultSet rs, int rowNum) throws SQLException {\n        return new TableRelationInformation(\n            rs.getString(\"table_name\"),\n            rs.getString(\"column_name\"),\n            rs.getString(\"foreign_table_name\"),\n            rs.getString(\"foreign_column_name\")\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/repository/InformationSchemaRepository.java",
    "content": "package org.blackdread.sqltojava.repository;\n\nimport java.util.List;\nimport org.blackdread.sqltojava.pojo.ColumnInformation;\nimport org.blackdread.sqltojava.pojo.TableInformation;\nimport org.blackdread.sqltojava.pojo.TableRelationInformation;\n\npublic interface InformationSchemaRepository {\n    List<TableRelationInformation> getAllTableRelationInformation(final String dbName);\n    List<ColumnInformation> getFullColumnInformationOfTable(final String dbName, final String tableName);\n    List<TableInformation> getAllTableInformation(final String dbName);\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/repository/MsSqlPureSqlInformationSchemaRepository.java",
    "content": "package org.blackdread.sqltojava.repository;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.stream.Collectors;\nimport org.blackdread.sqltojava.pojo.ColumnInformation;\nimport org.blackdread.sqltojava.pojo.TableInformation;\nimport org.blackdread.sqltojava.pojo.TableRelationInformation;\nimport org.blackdread.sqltojava.pojo.rowmaper.SqlServerColumnInformationRowMapper;\nimport org.blackdread.sqltojava.pojo.rowmaper.SqlServerTableInformationRowMapper;\nimport org.blackdread.sqltojava.pojo.rowmaper.TableRelationInformationRowMapper;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.context.annotation.Profile;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.io.ClassPathResource;\nimport org.springframework.core.io.Resource;\nimport org.springframework.core.io.support.PathMatchingResourcePatternResolver;\nimport org.springframework.core.io.support.ResourcePatternResolver;\nimport org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;\nimport org.springframework.stereotype.Repository;\n\n@Repository\n@Profile({ \"sqlserver\" })\npublic class MsSqlPureSqlInformationSchemaRepository implements InformationSchemaRepository {\n\n    private static final Logger log = LoggerFactory.getLogger(MsSqlPureSqlInformationSchemaRepository.class);\n    private static String ALL_TABLE_RELATIONAL_INFROMATION;\n    private static String FULL_COLUMN_INFORMATION_OF_TABLE;\n    private static String ALL_TABLE_INFORMATION;\n    private static final SqlServerTableInformationRowMapper TABLE_INFORMATION_MAPPER = new SqlServerTableInformationRowMapper();\n    private final NamedParameterJdbcTemplate template;\n\n    @Autowired\n    public MsSqlPureSqlInformationSchemaRepository(NamedParameterJdbcTemplate template, ConfigurableEnvironment env) {\n        String activeProfile = env.getActiveProfiles()[0];\n        ALL_TABLE_RELATIONAL_INFROMATION = readSqlFileByProfile(activeProfile, \"getAllTableRelationInformation\");\n        FULL_COLUMN_INFORMATION_OF_TABLE = readSqlFileByProfile(activeProfile, \"getFullColumnInformationOfTable\");\n        ALL_TABLE_INFORMATION = readSqlFileByProfile(activeProfile, \"getAllTableInformation\");\n        this.template = template;\n    }\n\n    @Override\n    public List<TableRelationInformation> getAllTableRelationInformation(final String schemaName) {\n        Map<String, ?> paramMap = Map.of(\"schemaName\", schemaName);\n        return template.queryForStream(ALL_TABLE_RELATIONAL_INFROMATION, paramMap, new TableRelationInformationRowMapper()).toList();\n    }\n\n    @Override\n    public List<ColumnInformation> getFullColumnInformationOfTable(final String schemaName, final String tableName) {\n        Map<String, ?> paramMap = Map.of(\"schemaName\", schemaName, \"tableName\", tableName);\n        return template.queryForStream(FULL_COLUMN_INFORMATION_OF_TABLE, paramMap, new SqlServerColumnInformationRowMapper()).toList();\n    }\n\n    public List<TableInformation> getAllTableInformation(final String schemaName) {\n        Map<String, ?> paramMap = Map.of(\"schemaName\", schemaName);\n        return template.queryForStream(ALL_TABLE_INFORMATION, paramMap, TABLE_INFORMATION_MAPPER).toList();\n    }\n\n    /**\n     * Loads a sql query file based on the active profile.\n     * For multiple profiles to use the same sql files they should be named as follows:\n     * sql/{profile1}_{profile1}-{queryName}.sql\n     * See mysql_mariadb-queryName.sql for an example.\n     * @param activeProfile\n     * @param queryName\n     * @return\n     */\n    private String readSqlFileByProfile(String activeProfile, String queryName) {\n        ClassLoader cl = this.getClass().getClassLoader();\n        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);\n        String pattern = String.format(\"classpath*:/sql/*%s*-%s.sql\", activeProfile, queryName);\n        log.info(\"Using pattern \" + pattern);\n        try {\n            Resource[] resources = resolver.getResources(pattern);\n            if (resources.length != 1) {\n                throw new IllegalArgumentException(String.format(\"Found %s when 1 was expected\", resources.length));\n            }\n            Resource r = resources[0];\n            log.info(\"Found resource \" + r.getFilename());\n\n            Resource resource = new ClassPathResource(\"sql/\" + r.getFilename());\n            InputStream inputStream = resource.getInputStream();\n\n            try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {\n                return reader.lines().collect(Collectors.joining(\"\\n\"));\n            } catch (IOException e) {\n                throw new RuntimeException(e);\n            }\n            //            return ResourceUtil.readString(r);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/repository/PureSqlInformationSchemaRepository.java",
    "content": "package org.blackdread.sqltojava.repository;\n\nimport java.io.IOException;\nimport java.util.List;\nimport java.util.Map;\nimport org.blackdread.sqltojava.pojo.ColumnInformation;\nimport org.blackdread.sqltojava.pojo.TableInformation;\nimport org.blackdread.sqltojava.pojo.TableRelationInformation;\nimport org.blackdread.sqltojava.pojo.rowmaper.ColumnInformationRowMapper;\nimport org.blackdread.sqltojava.pojo.rowmaper.TableInformationRowMapper;\nimport org.blackdread.sqltojava.pojo.rowmaper.TableRelationInformationRowMapper;\nimport org.blackdread.sqltojava.util.ResourceUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.context.annotation.Profile;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.io.Resource;\nimport org.springframework.core.io.support.PathMatchingResourcePatternResolver;\nimport org.springframework.core.io.support.ResourcePatternResolver;\nimport org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;\nimport org.springframework.stereotype.Repository;\n\n@Repository\n@Profile({ \"mysql\", \"mariadb\", \"postgresql\", \"oracle\" })\npublic class PureSqlInformationSchemaRepository implements InformationSchemaRepository {\n\n    private static final Logger log = LoggerFactory.getLogger(PureSqlInformationSchemaRepository.class);\n    private static String ALL_TABLE_RELATIONAL_INFROMATION;\n    private static String FULL_COLUMN_INFORMATION_OF_TABLE;\n    private static String ALL_TABLE_INFORMATION;\n    private static final TableInformationRowMapper TABLE_INFORMATION_MAPPER = new TableInformationRowMapper();\n    private final NamedParameterJdbcTemplate template;\n\n    @Autowired\n    public PureSqlInformationSchemaRepository(NamedParameterJdbcTemplate template, ConfigurableEnvironment env) {\n        String activeProfile = env.getActiveProfiles()[0];\n        ALL_TABLE_RELATIONAL_INFROMATION = readSqlFileByProfile(activeProfile, \"getAllTableRelationInformation\");\n        FULL_COLUMN_INFORMATION_OF_TABLE = readSqlFileByProfile(activeProfile, \"getFullColumnInformationOfTable\");\n        ALL_TABLE_INFORMATION = readSqlFileByProfile(activeProfile, \"getAllTableInformation\");\n        this.template = template;\n    }\n\n    @Override\n    public List<TableRelationInformation> getAllTableRelationInformation(final String schemaName) {\n        Map<String, ?> paramMap = Map.of(\"schemaName\", schemaName);\n        return template.queryForStream(ALL_TABLE_RELATIONAL_INFROMATION, paramMap, new TableRelationInformationRowMapper()).toList();\n    }\n\n    @Override\n    public List<ColumnInformation> getFullColumnInformationOfTable(final String schemaName, final String tableName) {\n        Map<String, ?> paramMap = Map.of(\"schemaName\", schemaName, \"tableName\", tableName);\n        return template.queryForStream(FULL_COLUMN_INFORMATION_OF_TABLE, paramMap, new ColumnInformationRowMapper()).toList();\n    }\n\n    public List<TableInformation> getAllTableInformation(final String schemaName) {\n        Map<String, ?> paramMap = Map.of(\"schemaName\", schemaName);\n        return template.queryForStream(ALL_TABLE_INFORMATION, paramMap, TABLE_INFORMATION_MAPPER).toList();\n    }\n\n    /**\n     * Loads a sql query file based on the active profile.\n     * For multiple profiles to use the same sql files they should be named as follows:\n     * sql/{profile1}_{profile1}-{queryName}.sql\n     * See mysql_mariadb-queryName.sql for an example.\n     * @param activeProfile\n     * @param queryName\n     * @return\n     */\n    private String readSqlFileByProfile(String activeProfile, String queryName) {\n        ClassLoader cl = this.getClass().getClassLoader();\n        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);\n        String pattern = String.format(\"classpath*:/sql/*%s*-%s.sql\", activeProfile, queryName);\n        log.info(\"Using pattern \" + pattern);\n        try {\n            Resource[] resources = resolver.getResources(pattern);\n            if (resources.length != 1) {\n                throw new IllegalArgumentException(String.format(\"Found %s when 1 was expected\", resources.length));\n            }\n            Resource r = resources[0];\n            log.info(\"Found resource \" + r.getFilename());\n            return ResourceUtil.readString(r);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/InformationSchemaService.java",
    "content": "package org.blackdread.sqltojava.service;\n\nimport java.util.List;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.pojo.ColumnInformation;\nimport org.blackdread.sqltojava.pojo.TableInformation;\nimport org.blackdread.sqltojava.pojo.TableRelationInformation;\nimport org.blackdread.sqltojava.repository.InformationSchemaRepository;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\n@Service\n@Transactional(readOnly = true)\npublic class InformationSchemaService {\n\n    private static final Logger log = LoggerFactory.getLogger(InformationSchemaService.class);\n\n    private final ApplicationProperties applicationProperties;\n\n    private final InformationSchemaRepository informationSchemaRepository;\n\n    public InformationSchemaService(\n        final ApplicationProperties applicationProperties,\n        final InformationSchemaRepository informationSchemaRepository\n    ) {\n        this.applicationProperties = applicationProperties;\n        this.informationSchemaRepository = informationSchemaRepository;\n    }\n\n    @Cacheable(\"InformationSchemaService.getAllTableRelationInformation\")\n    public List<TableRelationInformation> getAllTableRelationInformation() {\n        log.debug(\"getAllTableRelationInformation called\");\n        return informationSchemaRepository.getAllTableRelationInformation(applicationProperties.getDatabaseToExport());\n    }\n\n    @Cacheable(\"InformationSchemaService.getFullColumnInformationOfTable\")\n    public List<ColumnInformation> getFullColumnInformationOfTable(final String tableName) {\n        log.debug(\"getFullColumnInformationOfTable called for table: {}\", tableName);\n        return informationSchemaRepository.getFullColumnInformationOfTable(applicationProperties.getDatabaseToExport(), tableName);\n    }\n\n    @Cacheable(\"InformationSchemaService.getAllTableInformation\")\n    public List<TableInformation> getAllTableInformation() {\n        log.debug(\"getAllTableInformation called\");\n        return informationSchemaRepository.getAllTableInformation(applicationProperties.getDatabaseToExport());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/MsSqlJdlTypeService.java",
    "content": "package org.blackdread.sqltojava.service;\n\nimport static java.util.Map.entry;\nimport static org.blackdread.sqltojava.entity.JdlFieldEnum.*;\nimport static org.blackdread.sqltojava.entity.JdlFieldEnum.UUID;\nimport static org.blackdread.sqltojava.util.SqlUtils.COLUMN_TYPE_SIZE_REGEX;\n\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.regex.Matcher;\nimport org.apache.commons.lang3.ObjectUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.commons.lang3.math.NumberUtils;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.entity.JdlFieldEnum;\nimport org.blackdread.sqltojava.entity.SqlColumn;\nimport org.blackdread.sqltojava.util.SqlUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.Profile;\nimport org.springframework.stereotype.Service;\n\n@Service\n@Profile(\"sqlserver\")\npublic class MsSqlJdlTypeService implements SqlJdlTypeService {\n\n    private static final Logger log = LoggerFactory.getLogger(MsSqlJdlTypeService.class);\n    public static final int VARCHAR_MAX_LENGTH = 8000;\n    public static final int NVARCHAR_MAX_LENGTH = 4000;\n    public static final int COLUMN_TYPE_MAX_LENGTH_MAX_VALUE = -1;\n\n    private final ApplicationProperties properties;\n\n    public MsSqlJdlTypeService(ApplicationProperties properties) {\n        this.properties = properties;\n    }\n\n    private final Map<String, JdlFieldEnum> typeMap = Map.ofEntries(\n        entry(\"bit\", BOOLEAN),\n        entry(\"date\", LOCAL_DATE),\n        entry(\"time\", TIME_AS_TEXT),\n        entry(\"datetime\", INSTANT),\n        entry(\"datetime2\", INSTANT),\n        entry(\"smalldatetime\", INSTANT),\n        entry(\"datetimeoffset\", ZONED_DATE_TIME),\n        entry(\"real\", FLOAT),\n        entry(\"float\", DOUBLE),\n        entry(\"smallint\", INTEGER),\n        entry(\"int\", INTEGER),\n        entry(\"bigint\", LONG),\n        entry(\"tinyint\", INTEGER),\n        entry(\"money\", BIG_DECIMAL),\n        entry(\"numeric\", BIG_DECIMAL),\n        entry(\"decimal\", BIG_DECIMAL),\n        entry(\"char\", STRING), //char(max) is string with length up to 8000\n        entry(\"varchar\", STRING), //varchar(max) is string with length up to 8000\n        entry(\"nvarchar\", STRING), //nvarchar(max) is string with length up to 4000\n        entry(\"nchar\", STRING), //nchar(max) is string with length up to 4000\n        entry(\"text\", STRING_UNBOUNDED),\n        entry(\"ntext\", STRING_UNBOUNDED), // Added conversion for ntext (deprecated sql server type)\n        entry(\"binary\", BLOB),\n        entry(\"varbinary\", BLOB),\n        entry(\"image\", IMAGE_BLOB),\n        entry(\"varbinary(max)\", BLOB),\n        entry(\"varchar(max)\", TEXT_BLOB),\n        entry(\"nvarchar(max)\", TEXT_BLOB),\n        entry(\"uniqueidentifier\", UUID)\n    );\n\n    @Override\n    public Map<String, JdlFieldEnum> getTypeMap() {\n        return mergeOverrides(this.typeMap, properties.getJdlTypeOverrides());\n    }\n\n    @Override\n    public JdlFieldEnum sqlTypeToJdlType(String sqlType) {\n        sqlType = StringUtils.trim(sqlType);\n        final Matcher matcher = COLUMN_TYPE_SIZE_REGEX.matcher(sqlType);\n\n        String typeName = null;\n        if (matcher.matches()) {\n            Integer max = matcher.group(3) == null ? null : Integer.valueOf(matcher.group(3));\n            typeName = matcher.group(1).toLowerCase();\n            if (ObjectUtils.isNotEmpty(max)) {\n                if (max == COLUMN_TYPE_MAX_LENGTH_MAX_VALUE && typeName.equalsIgnoreCase(\"varbinary\")) {\n                    typeName = \"varbinary(max)\".toLowerCase();\n                } else if (max == COLUMN_TYPE_MAX_LENGTH_MAX_VALUE && typeName.equalsIgnoreCase(\"varchar\")) {\n                    typeName = \"varchar(max)\".toLowerCase();\n                } else if (max == COLUMN_TYPE_MAX_LENGTH_MAX_VALUE && typeName.equalsIgnoreCase(\"nvarchar\")) {\n                    typeName = \"nvarchar(max)\".toLowerCase();\n                }\n            }\n        }\n        return Optional.ofNullable(getTypeMap().get(typeName)).orElse(UNSUPPORTED);\n    }\n\n    @Override\n    public Integer calculateStringMaxLength(SqlColumn column) {\n        return SqlUtils.parseSqlSize(column.getType()).orElse(1);\n        //        String columnType = SqlUtils.parseSqlType(column.getType());\n        //        if (\"VARCHAR\".equalsIgnoreCase(columnType) && max == COLUMN_TYPE_MAX_VALUE) {\n        //            return VARCHAR_MAX_LENGTH;\n        //        }\n        //        if (\"NVARCHAR\".equalsIgnoreCase(columnType) && max == COLUMN_TYPE_MAX_VALUE) {\n        //            return NVARCHAR_MAX_LENGTH;\n        //        }\n        //        return SqlJdlTypeService.super.calculateStringMaxLength(column);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/MySqlJdlTypeService.java",
    "content": "package org.blackdread.sqltojava.service;\n\nimport static java.util.Map.entry;\nimport static org.blackdread.sqltojava.entity.JdlFieldEnum.*;\n\nimport java.util.Map;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.entity.JdlFieldEnum;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.Profile;\nimport org.springframework.stereotype.Service;\n\n@Service\n@Profile({ \"mysql\", \"mariadb\" })\npublic class MySqlJdlTypeService implements SqlJdlTypeService {\n\n    private static final Logger log = LoggerFactory.getLogger(MySqlJdlTypeService.class);\n\n    private final ApplicationProperties properties;\n\n    public MySqlJdlTypeService(ApplicationProperties properties) {\n        this.properties = properties;\n    }\n\n    private final Map<String, JdlFieldEnum> typeMap = Map.ofEntries(\n        entry(\"varchar\", STRING),\n        entry(\"char\", STRING),\n        entry(\"text\", STRING),\n        entry(\"tinytext\", STRING),\n        entry(\"mediumtext\", TEXT_BLOB),\n        entry(\"longtext\", TEXT_BLOB),\n        entry(\"tinyblob\", BLOB),\n        entry(\"blob\", BLOB),\n        entry(\"mediumblob\", BLOB),\n        entry(\"longblob\", BLOB),\n        entry(\"smallint\", INTEGER),\n        entry(\"mediumint\", INTEGER),\n        entry(\"int\", INTEGER),\n        entry(\"bigint\", LONG),\n        entry(\"float\", FLOAT),\n        entry(\"double\", DOUBLE),\n        entry(\"date\", LOCAL_DATE),\n        entry(\"enum\", ENUM),\n        entry(\"set\", ENUM),\n        entry(\"boolean\", BOOLEAN),\n        entry(\"tinyint\", BOOLEAN),\n        entry(\"bit\", BOOLEAN),\n        entry(\"decimal\", BIG_DECIMAL),\n        entry(\"datetime\", INSTANT),\n        entry(\"timestamp\", INSTANT),\n        /**\n         * Not support by base jhipster but to export database which has this type.\n         * See:\n         * https://blog.ippon.fr/2017/12/04/la-technologie-spatiale-au-service-de-jhipster/\n         * https://github.com/chegola/jhipster-spatial\n         * https://stackoverflow.com/questions/50122390/integration-of-postgis-with-jhipster\n         **/\n        entry(\"geometry\", GEOMETRY_AS_TEXT),\n        /**\n         * Not support by base jhipster but to export database which has this type.\n         */\n        entry(\"json\", JSON_AS_TEXT),\n        entry(\"time\", TIME_AS_TEXT),\n        entry(\"year\", YEAR_AS_TEXT)\n    );\n\n    @Override\n    public Map<String, JdlFieldEnum> getTypeMap() {\n        return mergeOverrides(this.typeMap, properties.getJdlTypeOverrides());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/OracleJdlTypeService.java",
    "content": "package org.blackdread.sqltojava.service;\n\nimport static java.util.Map.entry;\nimport static org.blackdread.sqltojava.entity.JdlFieldEnum.*;\n\nimport java.util.Map;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.entity.JdlFieldEnum;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.Profile;\nimport org.springframework.stereotype.Service;\n\n@Service\n@Profile(\"oracle\")\npublic class OracleJdlTypeService implements SqlJdlTypeService {\n\n    private static final Logger log = LoggerFactory.getLogger(OracleJdlTypeService.class);\n\n    private final ApplicationProperties properties;\n\n    public OracleJdlTypeService(ApplicationProperties properties) {\n        this.properties = properties;\n    }\n\n    private final Map<String, JdlFieldEnum> typeMap = Map.ofEntries(\n        entry(\"VARCHAR2\", STRING),\n        entry(\"NUMBER\", INTEGER),\n        entry(\"NUMBER(38)\", LONG),\n        entry(\"NUMBER(19,5)\", BIG_DECIMAL),\n        entry(\"FLOAT\", FLOAT),\n        entry(\"BLOB\", BLOB),\n        entry(\"TIMESTAMP\", INSTANT),\n        entry(\"DATE\", LOCAL_DATE),\n        entry(\"CHAR\", STRING),\n        entry(\"CLOB\", BLOB),\n        entry(\"NCHAR\", STRING),\n        entry(\"NVARCHAR2\", STRING),\n        entry(\"RAW\", UUID)\n    );\n\n    @Override\n    public Map<String, JdlFieldEnum> getTypeMap() {\n        return this.mergeOverrides(this.typeMap, properties.getJdlTypeOverrides());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/PostgresJdlTypeService.java",
    "content": "package org.blackdread.sqltojava.service;\n\nimport static java.util.Map.entry;\nimport static org.blackdread.sqltojava.entity.JdlFieldEnum.*;\n\nimport java.util.Map;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.entity.JdlFieldEnum;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.Profile;\nimport org.springframework.stereotype.Service;\n\n@Service\n@Profile(\"postgresql\")\npublic class PostgresJdlTypeService implements SqlJdlTypeService {\n\n    private static final Logger log = LoggerFactory.getLogger(PostgresJdlTypeService.class);\n\n    private final ApplicationProperties properties;\n\n    public PostgresJdlTypeService(ApplicationProperties properties) {\n        this.properties = properties;\n    }\n\n    private final Map<String, JdlFieldEnum> typeMap = Map.ofEntries(\n        entry(\"boolean\", BOOLEAN),\n        entry(\"date\", LOCAL_DATE),\n        entry(\"time without time zone\", TIME_AS_TEXT),\n        entry(\"time with time zone\", TIME_AS_TEXT),\n        entry(\"timestamp without time zone\", INSTANT),\n        entry(\"timestamp with time zone\", ZONED_DATE_TIME),\n        entry(\"real\", FLOAT),\n        entry(\"double precision\", DOUBLE),\n        entry(\"smallint\", INTEGER),\n        entry(\"integer\", INTEGER),\n        entry(\"bigint\", LONG),\n        entry(\"money\", BIG_DECIMAL),\n        entry(\"numeric\", BIG_DECIMAL),\n        entry(\"character\", STRING),\n        entry(\"character varying\", STRING),\n        entry(\"text\", STRING_UNBOUNDED),\n        entry(\"bytea\", BLOB),\n        entry(\"json\", JSON_AS_TEXT),\n        entry(\"uuid\", UUID)\n        //Map.entry(\"interval\", null),\n        //Map.entry(\"jsonb\", null),\n        //Map.entry(\"jsonpath\", null),\n        //Map.entry(\"macaddr\", STRING),\n        //Map.entry(\"macaddr8\", STRING),\n        //Map.entry(\"xml\", STRING)\n    );\n\n    @Override\n    public Map<String, JdlFieldEnum> getTypeMap() {\n        return mergeOverrides(this.typeMap, properties.getJdlTypeOverrides());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/SqlJdlTypeService.java",
    "content": "package org.blackdread.sqltojava.service;\n\nimport static org.blackdread.sqltojava.entity.JdlFieldEnum.UNSUPPORTED;\n\nimport com.google.common.collect.ImmutableMap;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Optional;\nimport org.blackdread.sqltojava.entity.JdlFieldEnum;\nimport org.blackdread.sqltojava.entity.SqlColumn;\nimport org.blackdread.sqltojava.util.SqlUtils;\n\npublic interface SqlJdlTypeService {\n    Map<String, JdlFieldEnum> getTypeMap();\n\n    default JdlFieldEnum sqlTypeToJdlType(final String sqlType) {\n        String typeName = SqlUtils.parseSqlType(sqlType);\n        JdlFieldEnum jdlType = Optional.ofNullable(getTypeMap().get(typeName)).orElse(UNSUPPORTED);\n        //orElseThrow(() -> new IllegalStateException(\"Unknown type: \" + typeName));\n        return jdlType;\n    }\n\n    default Map<String, JdlFieldEnum> mergeOverrides(\n        final Map<String, JdlFieldEnum> defaultTypeMap,\n        final Map<String, JdlFieldEnum> overrides\n    ) {\n        Map<String, JdlFieldEnum> typeMap = new HashMap<>(defaultTypeMap);\n        overrides.forEach((k, v) -> typeMap.merge(k, v, (v1, v2) -> v2));\n        return ImmutableMap.copyOf(typeMap);\n    }\n\n    default Integer calculateStringMaxLength(SqlColumn column) {\n        return SqlUtils.parseSqlSize(column.getType()).orElse(255);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/logic/ExportService.java",
    "content": "package org.blackdread.sqltojava.service.logic;\n\nimport static java.util.Map.entry;\nimport static java.util.Map.ofEntries;\n\nimport java.io.BufferedWriter;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.StandardOpenOption;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.config.ExportFileStructureType;\nimport org.blackdread.sqltojava.entity.JdlEntity;\nimport org.blackdread.sqltojava.exporter.ExportFileStructureConfig;\nimport org.blackdread.sqltojava.util.JdlUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class ExportService {\n\n    private static final Logger log = LoggerFactory.getLogger(ExportService.class);\n\n    private final ApplicationProperties properties;\n    private final ExportFileStructureConfig exportFileStructureConfig;\n\n    private final JdlService jdlService;\n\n    private final MustacheService mustacheService;\n\n    public ExportService(\n        final ApplicationProperties properties,\n        ExportFileStructureConfig exportFileStructureConfig,\n        JdlService jdlService,\n        MustacheService mustacheService\n    ) {\n        this.properties = properties;\n        this.exportFileStructureConfig = exportFileStructureConfig;\n        this.jdlService = jdlService;\n        this.mustacheService = mustacheService;\n    }\n\n    /**\n     * Exports jdl to string using mustache.java\n     * @param entities\n     * @return\n     */\n    public String exportString(final List<JdlEntity> entities) {\n        return mustacheService.executeTemplate(\n            exportFileStructureConfig.getExportMustacheTemplateFilename(),\n            resolveExportStructure(entities)\n        );\n    }\n\n    public Map<String, Object> resolveExportStructure(final List<JdlEntity> entities) {\n        if (ExportFileStructureType.SEPARATED.equals(exportFileStructureConfig.getExportFileStructureType())) {\n            return ofEntries(\n                entry(\"entities\", entities),\n                entry(\"relations\", jdlService.getRelations(entities)),\n                entry(\"options\", !properties.isRenderEntitiesOnly() ? JdlUtils.getOptions() : Collections.emptyList())\n            );\n        } else if (\n            ExportFileStructureType.GROUPED_RELATIONS_SEPARATE_VIEWS.equals(exportFileStructureConfig.getExportFileStructureType())\n        ) {\n            List<JdlEntity> tables = extractTables(entities);\n            List<JdlEntity> views = extractViews(entities);\n\n            return ofEntries(\n                entry(\"entities\", tables),\n                entry(\"groupedonetoonerelations\", jdlService.getGroupOneToOneRelations(tables)),\n                entry(\"groupedmanytoonerelations\", jdlService.getGroupManyToOneRelations(tables)),\n                entry(\"manytomanyrelations\", jdlService.getManyToManyRelations(tables)),\n                entry(\"views\", views),\n                entry(\"viewsrelations\", jdlService.getRelations(views)),\n                entry(\"options\", !properties.isRenderEntitiesOnly() ? JdlUtils.getOptions() : Collections.emptyList())\n            );\n        } else if (\n            ExportFileStructureType.RELATIONS_BEFORE_VIEWS_SEPARATE_VIEWS.equals(exportFileStructureConfig.getExportFileStructureType())\n        ) {\n            List<JdlEntity> tables = extractTables(entities);\n            List<JdlEntity> views = extractViews(entities);\n\n            return ofEntries(\n                entry(\"entities\", tables),\n                entry(\"onetoonerelations\", jdlService.getOneToOneRelations(tables)),\n                entry(\"manytoonerelations\", jdlService.getManyToOneRelations(tables)),\n                entry(\"manytomanyrelations\", jdlService.getManyToManyRelations(tables)),\n                entry(\"views\", views),\n                entry(\"viewsrelations\", jdlService.getRelations(views)),\n                entry(\"options\", !properties.isRenderEntitiesOnly() ? JdlUtils.getOptions() : Collections.emptyList())\n            );\n        }\n        throw new IllegalStateException(\"Unknown export file structure type\");\n    }\n\n    private static List<JdlEntity> extractViews(List<JdlEntity> entities) {\n        return entities.stream().filter(JdlEntity::isReadOnly).toList();\n    }\n\n    private static List<JdlEntity> extractTables(List<JdlEntity> entities) {\n        return entities.stream().filter(e -> !e.isReadOnly()).toList();\n    }\n\n    /**\n     * Exports jdl to file defined with export.path\n     * @param entities\n     * @return\n     */\n    public void export(final List<JdlEntity> entities) {\n        final String jdl = exportString(entities);\n        final Path path = properties.getExport().getPath();\n\n        log.info(\"Exporting into: {}\", path.toAbsolutePath());\n\n        if (Files.isDirectory(path)) {\n            log.error(\"Path is a directory: {}\", path.toAbsolutePath());\n            throw new IllegalArgumentException(\"Cannot export into a directory\");\n        }\n\n        try {\n            Files.deleteIfExists(path);\n        } catch (IOException e) {\n            log.error(\"An error occurred when deleting export file\");\n            throw new IllegalStateException(e);\n        }\n\n        try (BufferedWriter out = Files.newBufferedWriter(path, StandardOpenOption.CREATE)) {\n            out.write(jdl);\n            out.flush();\n        } catch (IOException e) {\n            log.error(\"Error\", e);\n            throw new IllegalStateException(e);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/logic/JdlService.java",
    "content": "package org.blackdread.sqltojava.service.logic;\n\nimport static org.blackdread.sqltojava.entity.JdlFieldEnum.*;\nimport static org.blackdread.sqltojava.util.NamingConventionUtil.*;\n\nimport java.util.*;\nimport java.util.stream.Collectors;\nimport org.apache.commons.lang3.StringUtils;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.entity.*;\nimport org.blackdread.sqltojava.entity.impl.JdlEntityImpl;\nimport org.blackdread.sqltojava.entity.impl.JdlFieldImpl;\nimport org.blackdread.sqltojava.entity.impl.JdlRelationGroupImpl;\nimport org.blackdread.sqltojava.entity.impl.JdlRelationImpl;\nimport org.blackdread.sqltojava.service.SqlJdlTypeService;\nimport org.blackdread.sqltojava.util.JdlUtils;\nimport org.blackdread.sqltojava.util.SqlUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class JdlService {\n\n    private static final Logger log = LoggerFactory.getLogger(JdlService.class);\n\n    private final SqlService sqlService;\n\n    private final SqlJdlTypeService sqlJdlTypeService;\n\n    private final ApplicationProperties properties;\n\n    public JdlService(final SqlService sqlService, final ApplicationProperties properties, final SqlJdlTypeService sqlJdlTypeService) {\n        this.sqlService = sqlService;\n        this.sqlJdlTypeService = sqlJdlTypeService;\n        this.properties = properties;\n    }\n\n    public List<JdlEntity> buildEntities() {\n        final List<SqlColumn> sqlColumns = sqlService.buildColumns();\n        // todo build entities for columns of native enums so we can later export to JDL the native enum and its values\n        return SqlUtils\n            .groupColumnsByTable(sqlColumns)\n            .entrySet()\n            .stream()\n            .map(this::buildEntity)\n            .filter(Optional::isPresent)\n            .map(Optional::get)\n            .sorted()\n            .collect(Collectors.toList());\n    }\n\n    public List<JdlRelation> getRelations(List<JdlEntity> entities) {\n        return entities.stream().flatMap(e -> e.getRelations().stream()).collect(Collectors.toList());\n    }\n\n    public List<JdlRelation> getOneToOneRelations(List<JdlEntity> entities) {\n        return entities\n            .stream()\n            .flatMap(e -> e.getRelations().stream())\n            .filter(f -> RelationType.OneToOne.equals(f.getRelationType()))\n            .collect(Collectors.toList());\n    }\n\n    public List<JdlRelation> getManyToOneRelations(List<JdlEntity> entities) {\n        return entities\n            .stream()\n            .flatMap(e -> e.getRelations().stream())\n            .filter(f -> RelationType.ManyToOne.equals(f.getRelationType()))\n            .collect(Collectors.toList());\n    }\n\n    public JdlRelationGroupImpl getGroupManyToOneRelations(List<JdlEntity> entities) {\n        List<JdlRelation> idRelations = entities\n            .stream()\n            .flatMap(e -> e.getRelations().stream())\n            .filter(f -> RelationType.ManyToOne.equals(f.getRelationType()))\n            .collect(Collectors.toList());\n\n        return new JdlRelationGroupImpl(RelationType.ManyToOne, idRelations);\n    }\n\n    public JdlRelationGroupImpl getGroupOneToOneRelations(List<JdlEntity> entities) {\n        List<JdlRelation> idRelations = entities\n            .stream()\n            .flatMap(e -> e.getRelations().stream())\n            .filter(f -> RelationType.OneToOne.equals(f.getRelationType()))\n            .collect(Collectors.toList());\n\n        return new JdlRelationGroupImpl(RelationType.OneToOne, idRelations);\n    }\n\n    public List<JdlRelation> getManyToManyRelations(List<JdlEntity> entities) {\n        return entities\n            .stream()\n            .flatMap(e -> e.getRelations().stream())\n            .filter(e -> RelationType.ManyToMany.equals(e.getRelationType()))\n            .collect(Collectors.toList());\n    }\n\n    private boolean nonDefaultPrimaryKeyFields(final JdlField f) {\n        return !isDefaultPrimaryKey(f);\n    }\n\n    private boolean isDefaultPrimaryKey(JdlField f) {\n        return f.isPrimaryKey() && f.getType().equals(LONG) && f.getName().equals(\"id\");\n    }\n\n    protected Optional<JdlEntity> buildEntity(final Map.Entry<SqlTable, List<SqlColumn>> entry) {\n        final List<JdlField> fields = entry\n            .getValue()\n            .stream()\n            .map(this::buildField)\n            .filter(Optional::isPresent)\n            .map(Optional::get)\n            .filter(this::nonDefaultPrimaryKeyFields)\n            .collect(Collectors.toList());\n\n        final List<JdlRelation> existingRelations = new ArrayList<>();\n\n        final List<JdlRelation> relations = entry\n            .getValue()\n            .stream()\n            .filter(SqlColumn::isForeignKey)\n            .map((SqlColumn column) -> buildRelation(column, sqlService.getTableOfForeignKey(column), existingRelations))\n            .filter(Optional::isPresent)\n            .map(Optional::get)\n            .sorted()\n            .collect(Collectors.toList());\n\n        String tableName = entry.getKey().getName();\n        String entityName = getEntityNameFormatted(tableName);\n        List<String> reserved = properties.getReservedList();\n\n        if (reserved.contains(entityName.toUpperCase())) {\n            String msg =\n                \"Skipping processing table [\" +\n                entry.getKey().getName() +\n                \"] because \" +\n                \" the transformed entity name [\" +\n                entityName +\n                \"] matches with one of the keywords \" +\n                reserved;\n            log.error(msg);\n            return Optional.empty();\n        }\n\n        JdlEntity jdlEntity = new JdlEntityImpl(\n            entityName,\n            properties.getAddTableNameJdl() ? tableName : null,\n            fields,\n            entry.getKey().getComment().orElse(null),\n            sqlService.isEnumTable(entry.getKey().getName()),\n            !entry.getKey().isUpdatable(),\n            sqlService.isPureManyToManyTable(entry.getKey().getName()),\n            relations\n        );\n        return Optional.of(jdlEntity);\n    }\n\n    private String getEntityNameFormatted(final String name) {\n        return JdlUtils.getEntityName(name, properties.getDatabaseObjectPrefix());\n    }\n\n    /**\n     * @param column Column from which to create field\n     * @return The field or empty if field is to be ignored\n     */\n    protected Optional<JdlField> buildField(final SqlColumn column) {\n        final String name;\n        JdlFieldEnum jdlType;\n        final String enumEntityName;\n        final String comment;\n        final boolean isNativeEnum = column.isNativeEnum();\n        String pattern = null;\n\n        if (sqlService.isEnumTable(column.getTable().getName())) return Optional.empty();\n\n        if (column.isForeignKey()) {\n            // check if table referenced is an enum, otherwise, skip\n            final SqlTable tableOfForeignKey = sqlService.getTableOfForeignKey(column);\n            if (!sqlService.isEnumTable(tableOfForeignKey.getName())) {\n                log.info(\"Skipped field of ({}) as ({}) is not an enum table\", column, tableOfForeignKey);\n                return Optional.empty();\n            }\n            jdlType = ENUM;\n            name = SqlUtils.changeToCamelCase(SqlUtils.removeIdFromEnd(column.getName()));\n            enumEntityName = StringUtils.capitalize(SqlUtils.changeToCamelCase(SqlUtils.removeIdFromEnd(tableOfForeignKey.getName())));\n            comment =\n                column\n                    .getComment()\n                    .map(comment1 -> tableOfForeignKey.getComment().map(c -> comment1 + \". \" + c).orElse(comment1))\n                    .orElse(tableOfForeignKey.getComment().orElse(null));\n        } else {\n            if (isNativeEnum) {\n                jdlType = ENUM;\n                name = SqlUtils.changeToCamelCase(toTitleCase(column.getName()).replace(\" \", \"\"));\n                // todo name of enumEntityName is not great but never mind\n                enumEntityName = StringUtils.capitalize(SqlUtils.changeToCamelCase(SqlUtils.removeIdFromEnd(column.getName())));\n            } else {\n                jdlType = sqlJdlTypeService.sqlTypeToJdlType(column.getType());\n                name = SqlUtils.changeToCamelCase(replaceSlavenChars(toTitleCase(column.getName())));\n                log.info(\"column name change sql to jdl format: {}, {}\", column.getName(), name);\n                enumEntityName = null;\n            }\n            if (jdlType == UNSUPPORTED) {\n                comment = String.join(column.getComment().orElse(\"\"), \" \", column.getType());\n            } else {\n                comment = column.getComment().orElse(null);\n            }\n            //    comment = (jdlType=UNSUPPORTED) column.getComment().orElse(null);\n        }\n\n        final Integer min;\n        final Integer max;\n        switch (jdlType) {\n            // We always define max for string\n            case STRING -> {\n                min = null;\n                max = sqlJdlTypeService.calculateStringMaxLength(column);\n            }\n            case TIME_AS_TEXT -> {\n                pattern = \"^(([0-1]\\\\d)|(2[0-3])):([0-5]\\\\d):([0-5]\\\\d)$\";\n                jdlType = STRING;\n                max = 8;\n                min = 8;\n            }\n            case YEAR_AS_TEXT -> {\n                pattern = \"^-?(\\\\d+)$\";\n                jdlType = STRING;\n                max = null;\n                min = null;\n            }\n            case GEOMETRY_AS_TEXT, JSON_AS_TEXT, STRING_UNBOUNDED -> {\n                jdlType = STRING;\n                max = null;\n                min = null;\n            }\n            default -> {\n                min = null;\n                max = null;\n            }\n        }\n\n        // Min and pattern are not set as we cannot guess it (unless we define it in comments -> parse)\n\n        return Optional.of(\n            new JdlFieldImpl(\n                jdlType,\n                name,\n                !column.isNullable(),\n                comment,\n                min,\n                max,\n                pattern,\n                enumEntityName,\n                isNativeEnum,\n                column.isUnique(),\n                column.isPrimaryKey()\n            )\n        );\n    }\n\n    /**\n     * @param column            Column from which to create relation, owner side of the relation\n     * @param inverseSideTable  The table referenced by the column of the owner side\n     * @param existingRelations Cache for checking already registered relations, needed to avoid name duplication\n     * @return The relation or empty if relation is to be ignored\n     */\n    protected Optional<JdlRelation> buildRelation(\n        final SqlColumn column,\n        final SqlTable inverseSideTable,\n        final List<JdlRelation> existingRelations\n    ) {\n        if (!column.isForeignKey()) throw new IllegalArgumentException(\"Cannot create a relation from a non foreign key\");\n\n        final SqlTable ownerSideTable = column.getTable();\n        final String tableName = ownerSideTable.getName();\n        final String columnName = column.getName();\n\n        final boolean isNullable = column.isNullable();\n\n        final boolean isUnique = column.isUnique();\n\n        if (sqlService.isEnumTable(inverseSideTable.getName())) {\n            log.info(\"Skipped relation of ({}) as ({}) is an enum table\", column, inverseSideTable);\n            return Optional.empty();\n        }\n\n        final boolean isPureManyToManyTable = sqlService.isPureManyToManyTable(tableName);\n\n        // it allows to have a clearer idea when reading the generated file\n        final String extraRelationComment = column.getTable().getComment().orElse(null);\n\n        final RelationType relationType;\n        if (isPureManyToManyTable) {\n            relationType = RelationType.ManyToMany;\n        } else {\n            if (isUnique) {\n                relationType = RelationType.OneToOne;\n            } else {\n                relationType = RelationType.ManyToOne;\n            }\n        }\n\n        // TeamMember{user(login) required} to User\n        final String inverseSideEntityName = getEntityNameFormatted(inverseSideTable.getName());\n\n        // We put always bidirectional but we have no way to generate good inverse name so we put the owner side name\n        final String ownerEntityName = getEntityNameFormatted(tableName);\n        final String inverseSideRelationName = buildInverseSideRelationName(\n            inverseSideEntityName,\n            ownerEntityName,\n            columnName,\n            existingRelations\n        );\n        boolean required = !isNullable;\n        if (required) {\n            if (ownerEntityName.equals(inverseSideEntityName)) {\n                String msg =\n                    \"Detected a Self Reference in the table \" +\n                    tableName +\n                    \". JHipster JDL currently does not support Reflexive relationships. \" +\n                    \"Set [nullable] as [true] for column [\" +\n                    columnName +\n                    \"] to fix errors when using the JDL with JHipster\";\n                log.warn(msg);\n                required = false;\n            }\n        }\n\n        final JdlRelationImpl relation = new JdlRelationImpl(\n            relationType,\n            properties.isAssumeBidirectional(),\n            required,\n            false,\n            ownerEntityName,\n            inverseSideEntityName,\n            SqlUtils.changeToCamelCase(SqlUtils.removeIdFromEnd(columnName)),\n            sqlService.getDisplayFieldOfTable(inverseSideTable),\n            column.getComment().orElse(null),\n            null,\n            inverseSideRelationName,\n            sqlService.getDisplayFieldOfTable(ownerSideTable),\n            extraRelationComment\n        );\n\n        existingRelations.add(relation);\n\n        return Optional.of(relation);\n    }\n\n    /**\n     * @param inverseSideEntityName The table name referenced by the column of the owner side\n     * @param ownerEntityName       Table name of column from which to create relation, owner side of the relation\n     * @param columnName            Column name from which to create relation, owner side of the relation\n     * @param existingRelations     Cache for checking already registered relations, needed to avoid name duplication\n     * @return Modified name of ownerEntity or full name consisting of ownerEntity and columnName\n     */\n    private String buildInverseSideRelationName(\n        String inverseSideEntityName,\n        String ownerEntityName,\n        String columnName,\n        List<JdlRelation> existingRelations\n    ) {\n        String possibleRelationName = JdlUtils.decapitalize(ownerEntityName);\n        // Looking for a full match of names within 1 entity\n        final boolean relationAlreadyExist = existingRelations\n            .stream()\n            .anyMatch(jdlRelation ->\n                ownerEntityName.equals(jdlRelation.getOwnerEntityName()) &&\n                possibleRelationName.equals(jdlRelation.getInverseSideRelationName().orElse(null)) &&\n                inverseSideEntityName.equals(jdlRelation.getInverseSideEntityName())\n            );\n\n        if (relationAlreadyExist) {\n            //As stated earlier, we have no way to generate a good reverse name, so we put the owner's side name.\n            //So we simply combine the relationship name and the column name\n            return possibleRelationName + \"Of\" + StringUtils.capitalize(SqlUtils.changeToCamelCase(SqlUtils.removeIdFromEnd(columnName)));\n        } else {\n            return possibleRelationName;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/logic/MustacheService.java",
    "content": "package org.blackdread.sqltojava.service.logic;\n\nimport com.github.mustachejava.DefaultMustacheFactory;\nimport com.github.mustachejava.Mustache;\nimport com.github.mustachejava.MustacheFactory;\nimport com.github.mustachejava.reflect.ReflectionObjectHandler;\nimport com.github.mustachejava.util.DecoratedCollection;\nimport java.io.IOException;\nimport java.io.StringWriter;\nimport java.util.Collection;\nimport java.util.Map;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.entity.impl.JdlEntityImpl;\nimport org.blackdread.sqltojava.entity.impl.JdlFieldImpl;\nimport org.blackdread.sqltojava.entity.impl.JdlRelationGroupImpl;\nimport org.blackdread.sqltojava.entity.impl.JdlRelationImpl;\nimport org.blackdread.sqltojava.view.mapper.JdlViewMapperImpl;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class MustacheService {\n\n    private static final Logger log = LoggerFactory.getLogger(MustacheService.class);\n    private static final String MUSTACHE_EXTENSION = \".mustache\";\n    private final MustacheFactory mf;\n\n    private final ApplicationProperties properties;\n\n    public MustacheService(ApplicationProperties properties) {\n        this.mf = getMustacheFactory();\n        this.properties = properties;\n    }\n\n    /**\n     * Load templates from resources/mustache.  The assumed extension is .mustache so only the file name needs to be specified.\n     * @param template\n     * @param context\n     * @return\n     */\n    public String executeTemplate(String template, Map<String, Object> context) {\n        Mustache m = mf.compile(template + MUSTACHE_EXTENSION);\n        try {\n            StringWriter writer = new StringWriter();\n            m.execute(writer, context).flush();\n            return replaceMultpleBlankLinesWithOne(writer.toString());\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private String replaceMultpleBlankLinesWithOne(String s) {\n        return s.replaceAll(\"([ \\\\tw]*\\\\n){3,}\", \"\\\\\\n\\\\\\n\").replaceAll(\"\\\\n\\\\n$\", \"\\\\\\n\");\n    }\n\n    /**\n     * Create a MustacheFactory with a MapstructBasedObjectHandler\n     * @return MustacheFactory\n     */\n    private MustacheFactory getMustacheFactory() {\n        DefaultMustacheFactory mf = new DefaultMustacheFactory(\"mustache\");\n        mf.setObjectHandler(new MapstructBasedObjectHandler());\n        return mf;\n    }\n\n    /**\n     * Use Mapstruct to map the JDL model to view DTOs for rendering with mustache.java\n     */\n    private class MapstructBasedObjectHandler extends ReflectionObjectHandler {\n\n        private static JdlViewMapperImpl mapper = new JdlViewMapperImpl();\n\n        @Override\n        public Object coerce(Object o) {\n            if (o instanceof JdlRelationGroupImpl) return mapper.relationToView((JdlRelationGroupImpl) o);\n            if (o instanceof JdlEntityImpl) return mapper.entityToView((JdlEntityImpl) o, properties.getUndefinedTypeHandling());\n            if (o instanceof JdlFieldImpl) return mapper.fieldToView((JdlFieldImpl) o);\n            if (o instanceof JdlRelationImpl) return mapper.relationToView((JdlRelationImpl) o);\n            if (o instanceof Collection) return new DecoratedCollection((Collection) o);\n            return super.coerce(o);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/logic/SqlService.java",
    "content": "package org.blackdread.sqltojava.service.logic;\n\nimport com.google.common.collect.Maps;\nimport java.util.Collection;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.stream.Collectors;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.config.DatabaseObjectTypesConfigEnum;\nimport org.blackdread.sqltojava.entity.SqlColumn;\nimport org.blackdread.sqltojava.entity.SqlTable;\nimport org.blackdread.sqltojava.entity.impl.SqlColumnImpl;\nimport org.blackdread.sqltojava.entity.impl.SqlTableImpl;\nimport org.blackdread.sqltojava.pojo.ColumnInformation;\nimport org.blackdread.sqltojava.pojo.TableInformation;\nimport org.blackdread.sqltojava.pojo.TableRelationInformation;\nimport org.blackdread.sqltojava.service.InformationSchemaService;\nimport org.blackdread.sqltojava.util.SqlUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\n@Service\n@Transactional(readOnly = true)\npublic class SqlService {\n\n    private static final Logger log = LoggerFactory.getLogger(SqlService.class);\n\n    private final ApplicationProperties applicationProperties;\n\n    private final InformationSchemaService informationSchemaService;\n\n    @Autowired\n    public SqlService(final ApplicationProperties applicationProperties, final InformationSchemaService informationSchemaService) {\n        this.applicationProperties = applicationProperties;\n        this.informationSchemaService = informationSchemaService;\n    }\n\n    // @Cacheable does not work when in same class so we loose a bit in efficiency but repo is cached as well so...\n\n    @Cacheable(\"SqlService.buildTables\")\n    public List<SqlTable> buildTables() {\n        log.debug(\"buildTables called\");\n        final List<String> ignoredTableNames = applicationProperties.getIgnoredTableNames();\n        return informationSchemaService\n            .getAllTableInformation()\n            .stream()\n            .filter(table -> includeType(table, applicationProperties.getDatabaseObjectTypesConfig()))\n            .filter(table -> !doesTableEndWithDetailKeyword(table))\n            .filter(table -> !isTableIgnored(ignoredTableNames, table))\n            .map(table -> new SqlTableImpl(table.getName(), table.getComment().orElse(null), table.getType(), table.isUpdateable()))\n            .collect(Collectors.toList());\n    }\n\n    private boolean includeType(TableInformation table, DatabaseObjectTypesConfigEnum databaseObjectTypesConfig) {\n        return switch (databaseObjectTypesConfig) {\n            case ALL -> true;\n            case TABLES -> table.getType().equals(\"BASE TABLE\");\n            case VIEWS -> table.getType().equals(\"VIEW\");\n        };\n    }\n\n    private boolean doesTableEndWithDetailKeyword(TableInformation table) {\n        String tablename = table.getName();\n        boolean result = tablename.toLowerCase().endsWith(\"_detail\");\n        if (result) {\n            String msg = String.format(\n                \"Skipped processing table [%s] which ends with the JDL keyword [Detail]. \" +\n                \"Please alter the table name to something else (for e.g., adding [details] as the suffix)\",\n                tablename\n            );\n            log.error(msg);\n        }\n        return result;\n    }\n\n    @Cacheable(\"SqlService.buildColumns\")\n    public List<SqlColumn> buildColumns() {\n        log.debug(\"buildColumns called\");\n        return buildTables()\n            .stream()\n            .map(table -> Maps.immutableEntry(table, informationSchemaService.getFullColumnInformationOfTable(table.getName())))\n            .map(entry ->\n                entry\n                    .getValue()\n                    .stream()\n                    .map(columnInformation -> {\n                        final String columnType = columnInformation.getType();\n\n                        // hard coded for now, we can later extract in some service, etc.\n                        final boolean isNativeEnum = columnType.startsWith(\"enum\") || columnType.startsWith(\"set\");\n\n                        return new SqlColumnImpl(\n                            entry.getKey(),\n                            columnInformation.getName(),\n                            columnType,\n                            columnInformation.isPrimary(),\n                            isForeignKey(entry.getKey().getName(), columnInformation.getName()),\n                            columnInformation.isNullable(),\n                            columnInformation.isUnique(),\n                            isNativeEnum,\n                            columnInformation.getDefaultValue().orElse(null),\n                            columnInformation.getComment()\n                        );\n                    })\n                    .collect(Collectors.toList())\n            )\n            .flatMap(Collection::stream)\n            .collect(Collectors.toList());\n    }\n\n    @Cacheable(\"SqlService.getTableOfForeignKey\")\n    public SqlTable getTableOfForeignKey(final SqlColumn column) {\n        log.debug(\"getTableOfForeignKey called: ({}) ({})\", column.getTable().getName(), column.getName());\n        return informationSchemaService\n            .getAllTableRelationInformation()\n            .stream()\n            .filter(e -> e.getTableName().equals(column.getTable().getName()))\n            .filter(e -> e.getColumnName().equals(column.getName()))\n            .findFirst()\n            .map(TableRelationInformation::getReferencedTableName)\n            .map(tableName -> buildTables().stream().filter(e -> e.getName().equals(tableName)).findFirst())\n            .map(sqlTable -> sqlTable.orElseThrow(() -> new IllegalStateException(\"Table not found or is ignored\")))\n            .orElseThrow(() -> new IllegalArgumentException(\"Column is not a foreign key\"));\n    }\n\n    /**\n     * Get the display field for a table.\n     * The display field to chosen as a column with a unique constraint the with a unique constraint that has the lowest original position.\n     * @param table\n     * @return\n     */\n    @Cacheable(\"SqlService.getDisplayFieldOfTable\")\n    public String getDisplayFieldOfTable(final SqlTable table) {\n        String tableName = table.getName();\n        log.debug(\"getDisplayFieldOfTable called: ({})\", tableName);\n        return informationSchemaService\n            .getFullColumnInformationOfTable(table.getName())\n            .stream()\n            .sorted(Comparator.comparingInt(ColumnInformation::getOrdinalPosition))\n            .filter(ColumnInformation::isUnique)\n            .filter(c -> !isForeignKey(tableName, c.getName()))\n            .findFirst()\n            .map(ColumnInformation::getName)\n            .orElse(null);\n    }\n\n    @Cacheable(\"SqlService.isEnumTable\")\n    public boolean isEnumTable(final String tableName) {\n        final List<ColumnInformation> table = informationSchemaService.getFullColumnInformationOfTable(tableName);\n\n        if (table.size() != 2) return false;\n\n        for (final ColumnInformation column : table) {\n            // Our design contract define that id and code/name is an enum table so logic is put here\n            if (\n                !column.getName().equalsIgnoreCase(\"id\") &&\n                (!column.getName().equalsIgnoreCase(\"code\") && !column.getName().equalsIgnoreCase(\"name\"))\n            ) return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Used to get enums values for an enum materialized with a table\n     *\n     * @param tableName Table name\n     * @return enum values\n     * @deprecated not implemented yet\n     */\n    @Cacheable(\"SqlService.getEnumValuesForTable\")\n    public List<String> getEnumValues(final String tableName) {\n        throw new IllegalStateException(\"todo\");\n    }\n\n    /**\n     * Used to get enums values for a native enum\n     *\n     * @param tableName  Table name\n     * @param columnName column name\n     * @return enum values\n     * @deprecated not implemented yet\n     */\n    @Cacheable(\"SqlService.getEnumValuesForColumn\")\n    public List<String> getEnumValues(final String tableName, final String columnName) {\n        throw new IllegalStateException(\"todo\");\n    }\n\n    /**\n     * Check if the column name passed from the table name specified is referencing an enum table\n     *\n     * @param tableName  Table containing the FK column\n     * @param columnName FK column that reference the enum table\n     * @return True if this column name is referencing an enum table\n     */\n    @Cacheable(\"SqlService.isForeignKeyFromAnEnumTable\")\n    public boolean isForeignKeyFromAnEnumTable(final String tableName, final String columnName) {\n        if (!isForeignKey(tableName, columnName)) return false;\n        return isEnumTable(SqlUtils.removeIdFromEnd(columnName));\n    }\n\n    /**\n     * @param tableName  Table to check\n     * @param columnName Column to check\n     * @return True if column is a foreign key\n     */\n    @Cacheable(\"SqlService.isForeignKey\")\n    public boolean isForeignKey(final String tableName, final String columnName) {\n        return informationSchemaService\n            .getAllTableRelationInformation()\n            .stream()\n            .filter(e -> e.getTableName().equals(tableName))\n            .anyMatch(e -> e.getColumnName().equals(columnName));\n    }\n\n    /**\n     * A pure many to many table is a table with 2 columns and both are foreign keys.\n     * <p>Other MtM tables add other columns and treated as real entities with MtO relations</p>\n     *\n     * @param tableName Table to check\n     * @return True if this table is a pure many to many table (2 columns, 2 FK)\n     */\n    @Cacheable(\"SqlService.isPureManyToManyTable\")\n    public boolean isPureManyToManyTable(final String tableName) {\n        final List<ColumnInformation> table = informationSchemaService.getFullColumnInformationOfTable(tableName);\n\n        if (table.size() != 2) return false;\n\n        for (final ColumnInformation column : table) {\n            if (!isForeignKey(tableName, column.getName())) return false;\n        }\n\n        return true;\n    }\n\n    private boolean isTableIgnored(final List<String> ignoredTableNames, final TableInformation table) {\n        return ignoredTableNames.contains(table.getName());\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/AppUtil.java",
    "content": "package org.blackdread.sqltojava.util;\n\nimport org.blackdread.sqltojava.listener.SetDatabaseProfileApplicationEventListener;\nimport org.springframework.boot.SpringApplication;\n\npublic final class AppUtil {\n\n    /**\n     * Utility method to configure application the same in both tests and production since the\n     * main method is not called when the tests run and the database profile needs to be set in\n     * ApplicationEnvironmentPreparedEvent which runs before the context is loaded.\n     * @param app\n     * @return\n     */\n    public static SpringApplication setup(SpringApplication app) {\n        app.addListeners(new SetDatabaseProfileApplicationEventListener());\n        return app;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/JdbcUtil.java",
    "content": "package org.blackdread.sqltojava.util;\n\npublic final class JdbcUtil {\n\n    /**\n     * This method assumes the jdbc url starts with \"jdbc:database_type:\"\n     * @param jdbcUrl\n     * @return\n     */\n    public static String getDatabaseTypeFromJdbcUrl(String jdbcUrl) {\n        String[] parts = jdbcUrl.split(\":\");\n        assert parts[0].equals(\"jdbc\");\n        return parts[1];\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/JdlUtils.java",
    "content": "package org.blackdread.sqltojava.util;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.validation.constraints.NotNull;\nimport org.apache.commons.lang3.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic final class JdlUtils {\n\n    private static final Logger log = LoggerFactory.getLogger(JdlUtils.class);\n\n    private JdlUtils() {}\n\n    @NotNull\n    public static String paginationAll() {\n        return \"paginate * with pagination\";\n    }\n\n    @NotNull\n    public static String serviceClassAll() {\n        return \"service * with serviceClass\";\n    }\n\n    @NotNull\n    public static String mapStructAll() {\n        return \"dto * with mapstruct\";\n    }\n\n    @NotNull\n    public static String angularSuffixAll(final String suffix) {\n        return \"angularSuffix * with \" + suffix;\n    }\n\n    @NotNull\n    public static String filterAll() {\n        return \"filter *\";\n    }\n\n    public static String getEntityName(String name, List<String> prefixes) {\n        String entityName = prefixes\n            .stream()\n            .filter(prefix -> name.startsWith(prefix))\n            .findFirst()\n            .map(s -> name.substring(s.length()))\n            .orElse(name);\n        return StringUtils.capitalize(SqlUtils.changeToCamelCase(entityName));\n    }\n\n    public static String decapitalize(String string) {\n        char c[] = string.toCharArray();\n        c[0] = Character.toLowerCase(c[0]);\n        return new String(c);\n    }\n\n    public static List<String> getOptions() {\n        List<String> options = new ArrayList<>();\n        options.add(JdlUtils.serviceClassAll());\n        options.add(JdlUtils.paginationAll());\n        options.add(JdlUtils.mapStructAll());\n        options.add(JdlUtils.filterAll());\n        return options;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/NamingConventionUtil.java",
    "content": "package org.blackdread.sqltojava.util;\n\nimport java.util.Arrays;\nimport java.util.stream.Collectors;\n\npublic final class NamingConventionUtil {\n\n    public static String replaceSlavenChars(String columnName) {\n        return columnName\n            .replace(\" \", \"\")\n            .replace(\"š\", \"s\")\n            .replace(\"č\", \"c\")\n            .replace(\"ž\", \"z\")\n            .replace(\"ć\", \"c\")\n            .replace(\"đ\", \"d\")\n            .replace(\" \", \"\")\n            .replace(\"Š\", \"S\")\n            .replace(\"Č\", \"C\")\n            .replace(\"Ž\", \"Z\")\n            .replace(\"Ć\", \"C\")\n            .replace(\"Đ\", \"D\");\n    }\n\n    public static String toTitleCase(String sentence) {\n        if (sentence == null || sentence.isEmpty()) {\n            return sentence;\n        }\n        if (!sentence.contains(\" \")) {\n            return sentence;\n        }\n        return Arrays\n            .stream(sentence.split(\" \"))\n            .map(word -> Character.toUpperCase(word.charAt(0)) + word.substring(1).toLowerCase())\n            .collect(Collectors.joining(\" \"));\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/ResourceUtil.java",
    "content": "package org.blackdread.sqltojava.util;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.stream.Collectors;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.io.Resource;\n\npublic final class ResourceUtil {\n\n    private static final Logger log = LoggerFactory.getLogger(ResourceUtil.class);\n\n    public static String readString(Resource resource) {\n        try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))) {\n            return reader.lines().collect(Collectors.joining(System.lineSeparator()));\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    public static String readString(String path) {\n        try {\n            InputStream is = ResourceUtil.class.getClassLoader().getResourceAsStream(path);\n            String text = new String(is.readAllBytes(), StandardCharsets.UTF_8);\n            return text;\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    public static String getFirstExistingResourcePath(String fileName, String... paths) {\n        for (String path : paths) {\n            if (ResourceUtil.class.getResource(path) != null) {\n                log.info(String.format(\"%s found at %s\", fileName, path));\n                return path;\n            } else {\n                log.info(String.format(\"%s not found at %s\", fileName, path));\n            }\n        }\n        throw new RuntimeException(String.format(\"Could not find %s\", fileName));\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/SqlUtils.java",
    "content": "package org.blackdread.sqltojava.util;\n\nimport static com.google.common.base.CaseFormat.LOWER_CAMEL;\nimport static java.util.Optional.empty;\n\nimport com.google.common.base.CaseFormat;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\nimport org.apache.commons.lang3.StringUtils;\nimport org.blackdread.sqltojava.entity.SqlColumn;\nimport org.blackdread.sqltojava.entity.SqlTable;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic final class SqlUtils {\n\n    private static final Logger log = LoggerFactory.getLogger(SqlUtils.class);\n\n    public static final Pattern COLUMN_TYPE_SIZE_REGEX = Pattern.compile(\"(^[a-z0-9\\\\s]+)(\\\\((\\\\-?[0-9]+)\\\\))?$\", Pattern.CASE_INSENSITIVE);\n\n    private SqlUtils() {}\n\n    /**\n     * @param value A string that might ends with \"_id\" or \"Id\"\n     * @return Value without any ID suffix\n     */\n    public static String removeIdFromEnd(final String value) {\n        return value.toLowerCase().endsWith(\"_id\")\n            ? value.substring(0, value.length() - 3)\n            : value.endsWith(\"Id\") ? value.substring(0, value.length() - 2) : value;\n    }\n\n    public static String changeToCamelCase(final String value) {\n        if (value.contains(\"_\")) {\n            return CaseFormat.LOWER_UNDERSCORE.to(LOWER_CAMEL, value);\n        } else if (value.equals(value.toUpperCase())) {\n            // If the string is in all uppercase, convert it to lowercase\n            return value.toLowerCase();\n        } else {\n            // If the string contains uppercase letters in the middle, split the string into words\n            // based on the uppercase letters, then join the words with the first word in lowercase\n            // and the rest of the words in their original case\n            String[] words = value.split(\"(?=[A-Z])\");\n            String res = Stream.of(words).map(word -> word.equals(words[0]) ? word.toLowerCase() : word).collect(Collectors.joining());\n            return changeIdToLowerCase(res).replace(\"ID\", \"Id\");\n        }\n    }\n\n    public static String changeIdToLowerCase(final String value) {\n        if (value == null || value.isEmpty()) {\n            return value;\n        }\n        if (value.startsWith(\"iD\") && Character.isUpperCase(value.charAt(2))) {\n            return \"id\" + value.substring(2);\n        }\n        return value;\n    }\n\n    public static Map<SqlTable, List<SqlColumn>> groupColumnsByTable(final List<SqlColumn> sqlColumns) {\n        return sqlColumns.stream().collect(Collectors.groupingBy(SqlColumn::getTable, Collectors.toList()));\n    }\n\n    public static Optional<Integer> parseSqlSize(String value) {\n        value = StringUtils.trim(value);\n        final Matcher matcher = COLUMN_TYPE_SIZE_REGEX.matcher(value);\n\n        if (\"character varying\".equalsIgnoreCase(value)) {\n            // quick fix due to new regex used -> \"matcher.matches()\" returns true\n            return empty();\n        }\n\n        if (matcher.matches()) {\n            return Optional.of(Integer.valueOf(matcher.group(3)));\n        }\n        log.warn(\"Did not find sql size from: {}\", value);\n        return empty();\n    }\n\n    public static String parseSqlType(String value) {\n        // todo: Oracle Bigint, BigDecimal\n        if (value.equals(\"NUMBER(38)\") || value.equals(\"NUMBER(19,5)\")) {\n            return value;\n        }\n        return value.split(\"\\\\(\")[0];\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/JdlCommentView.java",
    "content": "package org.blackdread.sqltojava.view;\n\nimport java.util.Optional;\n\n/**\n * Methods for comments in the view\n */\npublic interface JdlCommentView {\n    Optional<String> getComment();\n\n    default String getImplComment(String comment) {\n        return (comment != null) ? \"// \" + comment : null;\n    }\n\n    default String getDocComment(String comment) {\n        return (comment != null) ? \"/** \" + comment + \" */\" : null;\n    }\n\n    default String getDocComment() {\n        return getDocComment(getComment().orElse(null));\n    }\n\n    default String getImplComment() {\n        return getImplComment(getComment().orElse(null));\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/JdlEntityView.java",
    "content": "package org.blackdread.sqltojava.view;\n\nimport static org.slf4j.LoggerFactory.getLogger;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\nimport org.blackdread.sqltojava.config.UndefinedJdlTypeHandlingEnum;\nimport org.blackdread.sqltojava.entity.JdlEntity;\nimport org.blackdread.sqltojava.entity.JdlField;\nimport org.slf4j.Logger;\n\n/**\n * Methods for JDL entities in the view\n */\npublic interface JdlEntityView extends JdlEntity, JdlCommentView {\n    UndefinedJdlTypeHandlingEnum getUndefinedJdlTypeHandling();\n\n    default String getType() {\n        return (isEnumEntity()) ? \"enum\" : \"entity\";\n    }\n\n    default String tableName() {\n        return (getTableName() != null) ? String.format(\"(%s)\", getTableName()) : null;\n    }\n\n    default List<JdlField> filteredFields() {\n        return getFields().stream().filter(f -> filterUnsupported(getUndefinedJdlTypeHandling(), f)).collect(Collectors.toList());\n    }\n\n    /**\n     * Filters fields and throws error based on UndefinedJdlTypeHandling\n     *\n     * @return\n     */\n    default boolean filterUnsupported(UndefinedJdlTypeHandlingEnum undefinedJdlTypeHandling, JdlField field) {\n        switch (field.getType()) {\n            case UNSUPPORTED -> {\n                switch (undefinedJdlTypeHandling) {\n                    case UNSUPPORTED -> {\n                        return true;\n                    }\n                    case SKIP -> {\n                        log().warn(\"Skipping unsupportd field {}\", field);\n                        return false;\n                    }\n                    case ERROR -> throw new RuntimeException(String.format(\"Unsupported jdl type %s\", field));\n                    //                    case ERROR -> {\n                    //                        log().error(\"Unsupported jdl type {}\", field);\n                    //                        return false;\n                    //                    }\n                    default -> throw new RuntimeException(\n                        String.format(\"Unhandled UndefinedJdlTypeHandlingEnum: %s\", undefinedJdlTypeHandling)\n                    );\n                }\n            }\n            default -> {\n                return true;\n            }\n        }\n    }\n\n    private static Logger log() {\n        final class LogHolder {\n\n            private static final Logger LOGGER = getLogger(JdlEntityView.class);\n        }\n        return LogHolder.LOGGER;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/JdlFieldView.java",
    "content": "package org.blackdread.sqltojava.view;\n\nimport com.google.common.base.Joiner;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.validation.constraints.NotNull;\nimport org.blackdread.sqltojava.entity.JdlField;\nimport org.blackdread.sqltojava.entity.JdlFieldEnum;\n\n/**\n * Methods for JDL fields in the view\n */\npublic interface JdlFieldView extends JdlField, JdlCommentView {\n    //TODO This validation should be handled in JdlService\n    default String getTypeName() {\n        JdlFieldEnum type = getType();\n        return switch (type) {\n            case ENUM -> getEnumEntityName()\n                .orElseThrow(() -> new IllegalStateException(\"An enum field must have its enum entity name set\"));\n            default -> ((\"UUID\".equals(type.name())) ? type.name() : type.toCamelUpper());\n        };\n    }\n\n    default String constraints() {\n        List<String> constraints = new ArrayList<>();\n        if (renderRequired()) constraints.add(requiredConstraint());\n        if (isUnique()) constraints.add(uniqueConstraint());\n        getMin().ifPresent(min -> constraints.add(minConstraint(min)));\n        getMax().ifPresent(max -> constraints.add(maxConstraint(max)));\n        getPattern().ifPresent(pattern -> constraints.add(patternConstraint(pattern)));\n        return (!constraints.isEmpty()) ? \" \".concat(Joiner.on(\" \").join(constraints)) : null;\n    }\n\n    // TODO do not write required when field is primary key\n    default boolean renderRequired() {\n        // if (!isPrimaryKey() && isRequired() && ) constraints.add(JdlUtils.validationRequired());\n        return isRequired() && !(getName().equals(\"id\") && getType().equals(JdlFieldEnum.UUID));\n    }\n\n    @NotNull\n    default String requiredConstraint() {\n        return \"required\";\n    }\n\n    @NotNull\n    default String uniqueConstraint() {\n        return \"unique\";\n    }\n\n    default String minConstraint(int min) {\n        return switch (getType()) {\n            case STRING -> validationMinLength(min);\n            default -> validationMin(min);\n        };\n    }\n\n    default String maxConstraint(int max) {\n        return switch (getType()) {\n            case STRING -> validationMaxLength(max);\n            default -> validationMax(max);\n        };\n    }\n\n    //TODO This validation should be handled in JdlService\n    default String patternConstraint(String pattern) {\n        return switch (getType()) {\n            case STRING -> validationPattern(pattern);\n            default -> throw new RuntimeException(\"Only String can have a pattern\");\n        };\n    }\n\n    @NotNull\n    default String validationMax(final int max) {\n        return \"max(\" + max + \")\";\n    }\n\n    @NotNull\n    default String validationMin(final int min) {\n        return \"min(\" + min + \")\";\n    }\n\n    default String validationMaxLength(final int max) {\n        return \"maxlength(\" + max + \")\";\n    }\n\n    @NotNull\n    default String validationMinLength(final int min) {\n        return \"minlength(\" + min + \")\";\n    }\n\n    @NotNull\n    default String validationPattern(final String pattern) {\n        return \"pattern(/\" + pattern + \"/)\";\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/JdlRelationGroupView.java",
    "content": "package org.blackdread.sqltojava.view;\n\nimport javax.annotation.concurrent.Immutable;\nimport javax.annotation.concurrent.ThreadSafe;\n\n@Immutable\n@ThreadSafe\npublic interface JdlRelationGroupView {}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/JdlRelationView.java",
    "content": "package org.blackdread.sqltojava.view;\n\nimport java.util.Optional;\nimport org.blackdread.sqltojava.entity.JdlRelation;\nimport org.blackdread.sqltojava.entity.RelationType;\n\n/**\n * Methods for JDL relations in the view\n */\npublic interface JdlRelationView extends JdlRelation, JdlCommentView {\n    default String getType() {\n        return getRelationType().toJdl();\n    }\n\n    default boolean isPureManyToMany() {\n        return getRelationType() == RelationType.ManyToMany;\n    }\n\n    default String getOwnerDocComment() {\n        return getDocComment(getOwnerComment().orElse(null));\n    }\n\n    default boolean hasComments() {\n        return getOwnerComment().isPresent() || getInverseSideComment().isPresent();\n    }\n\n    default String getInverseDocComment() {\n        return getDocComment(getInverseSideComment().orElse(null));\n    }\n\n    default String getOwnerConfig() {\n        return \"{\" + getOwnerRelationName() + getRelationConfig(getOwnerDisplayField(), isOwnerRequired()) + \"}\";\n    }\n\n    default String getInverseConfig() {\n        if (isBidirectional()) {\n            return (\n                \"{\" +\n                getInverseSideRelationName().orElse(\"\") +\n                getRelationConfig(getInverseSideDisplayField(), isInverseSideRequired()) +\n                \"}\"\n            );\n        } else {\n            return null;\n        }\n    }\n\n    default String getDisplayField(Optional<String> relation) {\n        return relation.map(displayName -> \"(\" + displayName + \")\").orElse(\"\");\n    }\n\n    default String getRelationConfig(Optional<String> relation, boolean required) {\n        return getDisplayField(relation) + ((required) ? \" required\" : \"\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/impl/JdlEntityViewImpl.java",
    "content": "package org.blackdread.sqltojava.view.impl;\n\nimport java.util.List;\nimport javax.annotation.Nullable;\nimport javax.annotation.concurrent.Immutable;\nimport javax.annotation.concurrent.ThreadSafe;\nimport org.blackdread.sqltojava.config.UndefinedJdlTypeHandlingEnum;\nimport org.blackdread.sqltojava.entity.JdlField;\nimport org.blackdread.sqltojava.entity.JdlRelation;\nimport org.blackdread.sqltojava.entity.impl.JdlEntityImpl;\nimport org.blackdread.sqltojava.view.JdlEntityView;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n@Immutable\n@ThreadSafe\npublic class JdlEntityViewImpl extends JdlEntityImpl implements JdlEntityView {\n\n    private static final Logger log = LoggerFactory.getLogger(JdlEntityViewImpl.class);\n\n    private final UndefinedJdlTypeHandlingEnum undefinedJdlTypeHandling;\n\n    /**\n     * Constructory based on super\n     * @param name\n     * @param tableName\n     * @param fields\n     * @param comment\n     * @param enumEntity\n     * @param readOnly\n     * @param pureManyToMany\n     * @param relations\n     */\n    public JdlEntityViewImpl(\n        String name,\n        String tableName,\n        List<JdlField> fields,\n        @Nullable String comment,\n        boolean enumEntity,\n        boolean readOnly,\n        boolean pureManyToMany,\n        List<JdlRelation> relations,\n        UndefinedJdlTypeHandlingEnum undefinedJdlTypeHandling\n    ) {\n        super(name, tableName, fields, comment, enumEntity, readOnly, pureManyToMany, relations);\n        this.undefinedJdlTypeHandling = undefinedJdlTypeHandling;\n    }\n\n    @Override\n    public UndefinedJdlTypeHandlingEnum getUndefinedJdlTypeHandling() {\n        return undefinedJdlTypeHandling;\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/impl/JdlFieldViewImpl.java",
    "content": "package org.blackdread.sqltojava.view.impl;\n\nimport javax.annotation.Nullable;\nimport javax.annotation.concurrent.Immutable;\nimport javax.annotation.concurrent.ThreadSafe;\nimport org.blackdread.sqltojava.entity.JdlFieldEnum;\nimport org.blackdread.sqltojava.entity.impl.JdlFieldImpl;\nimport org.blackdread.sqltojava.service.logic.JdlService;\nimport org.blackdread.sqltojava.view.JdlFieldView;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n@Immutable\n@ThreadSafe\npublic class JdlFieldViewImpl extends JdlFieldImpl implements JdlFieldView {\n\n    private static final Logger log = LoggerFactory.getLogger(JdlService.class);\n\n    /**\n     * Constructory based on super\n     * @param type\n     * @param name\n     * @param required\n     * @param comment\n     * @param min\n     * @param max\n     * @param pattern\n     * @param enumEntityName\n     * @param nativeEnum\n     * @param unique\n     * @param primaryKey\n     */\n    public JdlFieldViewImpl(\n        JdlFieldEnum type,\n        String name,\n        boolean required,\n        @Nullable String comment,\n        @Nullable Integer min,\n        @Nullable Integer max,\n        @Nullable String pattern,\n        @Nullable String enumEntityName,\n        Boolean nativeEnum,\n        Boolean unique,\n        Boolean primaryKey\n    ) {\n        super(type, name, required, comment, min, max, pattern, enumEntityName, nativeEnum, unique, primaryKey);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/impl/JdlRelationGroupViewImpl.java",
    "content": "package org.blackdread.sqltojava.view.impl;\n\nimport java.util.List;\nimport java.util.Optional;\nimport org.blackdread.sqltojava.entity.JdlRelation;\nimport org.blackdread.sqltojava.entity.RelationType;\nimport org.blackdread.sqltojava.entity.impl.JdlRelationGroupImpl;\n\npublic class JdlRelationGroupViewImpl extends JdlRelationGroupImpl {\n\n    public JdlRelationGroupViewImpl(RelationType relationType, List<JdlRelation> relations) {\n        super(relationType, relations);\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/impl/JdlRelationViewImpl.java",
    "content": "package org.blackdread.sqltojava.view.impl;\n\nimport javax.annotation.Nullable;\nimport javax.annotation.concurrent.Immutable;\nimport javax.annotation.concurrent.ThreadSafe;\nimport org.blackdread.sqltojava.entity.RelationType;\nimport org.blackdread.sqltojava.entity.impl.JdlRelationImpl;\nimport org.blackdread.sqltojava.view.JdlRelationView;\n\n@Immutable\n@ThreadSafe\npublic class JdlRelationViewImpl extends JdlRelationImpl implements JdlRelationView {\n\n    /**\n     * Constructory based on super\n     * @param relationType\n     * @param bidirectional\n     * @param ownerRequired\n     * @param inverseSideRequired\n     * @param ownerEntityName\n     * @param inverseSideEntityName\n     * @param ownerRelationName\n     * @param ownerDisplayField\n     * @param ownerComment\n     * @param inverseSideComment\n     * @param inverseSideRelationName\n     * @param inverseSideDisplayField\n     * @param comment\n     */\n    public JdlRelationViewImpl(\n        RelationType relationType,\n        boolean bidirectional,\n        boolean ownerRequired,\n        boolean inverseSideRequired,\n        String ownerEntityName,\n        String inverseSideEntityName,\n        String ownerRelationName,\n        @Nullable String ownerDisplayField,\n        @Nullable String ownerComment,\n        @Nullable String inverseSideComment,\n        @Nullable String inverseSideRelationName,\n        @Nullable String inverseSideDisplayField,\n        @Nullable String comment\n    ) {\n        super(\n            relationType,\n            bidirectional,\n            ownerRequired,\n            inverseSideRequired,\n            ownerEntityName,\n            inverseSideEntityName,\n            ownerRelationName,\n            ownerDisplayField,\n            ownerComment,\n            inverseSideComment,\n            inverseSideRelationName,\n            inverseSideDisplayField,\n            comment\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/mapper/JdlViewMapper.java",
    "content": "package org.blackdread.sqltojava.view.mapper;\n\nimport org.blackdread.sqltojava.config.UndefinedJdlTypeHandlingEnum;\nimport org.blackdread.sqltojava.entity.impl.JdlEntityImpl;\nimport org.blackdread.sqltojava.entity.impl.JdlFieldImpl;\nimport org.blackdread.sqltojava.entity.impl.JdlRelationGroupImpl;\nimport org.blackdread.sqltojava.entity.impl.JdlRelationImpl;\nimport org.blackdread.sqltojava.view.impl.JdlEntityViewImpl;\nimport org.blackdread.sqltojava.view.impl.JdlFieldViewImpl;\nimport org.blackdread.sqltojava.view.impl.JdlRelationGroupViewImpl;\nimport org.blackdread.sqltojava.view.impl.JdlRelationViewImpl;\nimport org.mapstruct.Mapper;\n\n/**\n * Generate Mapstruct mapper sources on compile\n */\n@Mapper(componentModel = \"spring\", uses = OptionalUtils.class)\npublic interface JdlViewMapper {\n    JdlEntityViewImpl entityToView(JdlEntityImpl jdlEntity, UndefinedJdlTypeHandlingEnum undefinedJdlTypeHandling);\n    JdlFieldViewImpl fieldToView(JdlFieldImpl jdlField);\n    JdlRelationViewImpl relationToView(JdlRelationImpl jdlRelation);\n    JdlRelationGroupViewImpl relationToView(JdlRelationGroupImpl jdlRelation);\n}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/mapper/OptionalUtils.java",
    "content": "package org.blackdread.sqltojava.view.mapper;\n\nimport java.util.Optional;\n\n/**\n * Used to handle Optional with Mapstruct\n */\npublic class OptionalUtils {\n\n    private OptionalUtils() {}\n\n    public static <T> T fromOptional(Optional<T> optional) {\n        return optional.orElse(null);\n    }\n}\n"
  },
  {
    "path": "src/main/resources/application.yml",
    "content": "spring:\n    datasource:\n        type: com.zaxxer.hikari.HikariDataSource\n        url: jdbc:mysql://localhost:3306/?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC\n        username: root\n        password:\n        hikari:\n            data-source-properties:\n                cachePrepStmts: true\n                prepStmtCacheSize: 250\n                prepStmtCacheSqlLimit: 2048\n                useServerPrepStmts: true\n    flyway:\n        enabled: false\n\napplication:\n    reserved-keywords: classpath:reserved/keywords.json\n    database-to-export: dbo\n    database_object_types_config: ALL # TABLES, ViEWS, ALL\n    render_entities_only: false\n    assume_bidirectional: false\n    database-object-prefix:\n        - t_\n        - v_\n    add_table_name_jdl: true\n    undefined_type_handling: ERROR\n    jdl-type-overrides:\n        my_type: FLOAT # Example JDL type override\n    ignored-table-names:\n        - databasechangelog\n        - databasechangeloglock\n        - QRTZ_BLOB_TRIGGERS\n        - QRTZ_CALENDARS\n        - QRTZ_CRON_TRIGGERS\n        - QRTZ_FIRED_TRIGGERS\n        - QRTZ_JOB_DETAILS\n        - QRTZ_LOCKS\n        - QRTZ_PAUSED_TRIGGER_GRPS\n        - QRTZ_SCHEDULER_STATE\n        - QRTZ_SIMPLE_TRIGGERS\n        - QRTZ_SIMPROP_TRIGGERS\n        - QRTZ_TRIGGERS\n        - MSreplication_options\n        - spt_fallback_db\n        - spt_fallback_dev\n        - spt_fallback_usg\n        - spt_monitor\n        - spt_values\n    export:\n        path: ./my-project-jdl.jh\n        type: jdl\n        export-file-structure-type: GROUPED_RELATIONS_SEPARATE_VIEWS\n        export-mustache-template-filename-optional:\n"
  },
  {
    "path": "src/main/resources/mustache/application-entities-relations-views.mustache",
    "content": "{{> entities}}\n\n{{> onetoonerelations}}\n\n{{> manytoonerelations}}\n\n{{> manytomanyrelations}}\n\n{{> views}}\n\n{{> viewsrelations}}\n\n{{> options}}\n"
  },
  {
    "path": "src/main/resources/mustache/application-grouped-relations-separate-views.mustache",
    "content": "{{> entities}}\n\n{{> groupedonetoonerelations}}\n\n{{> groupedmanytoonerelations}}\n\n{{> manytomanyrelations}}\n\n{{> views}}\n\n{{> viewsrelations}}\n\n{{> options}}\n"
  },
  {
    "path": "src/main/resources/mustache/application.mustache",
    "content": "{{> entities}}\n\n{{> relations}}\n\n{{> options}}\n"
  },
  {
    "path": "src/main/resources/mustache/entities.mustache",
    "content": "{{#entities}}\n{{^value.isPureManyToMany}}\n{{#value.comment}}\n{{value.docComment}}\n{{/value.comment}}\n{{#value.isReadOnly}}\n@readOnly\n{{/value.isReadOnly}}\n{{value.type}} {{value.name}}{{value.tableName}} {\n{{#value.filteredFields}}\n{{#value.comment}}\n    {{value.docComment}}\n{{/value.comment}}\n    {{value.name}} {{value.typeName}}{{value.constraints}}{{^last}},{{/last}}\n{{/value.filteredFields}}\n}\n{{^last}}{{/last}}\n{{/value.isPureManyToMany}}\n{{/entities}}\n{{^entities}}\n// No entities were found for which JDL is to be generated. Please review console logs\n{{/entities}}"
  },
  {
    "path": "src/main/resources/mustache/groupedmanytoonerelations.mustache",
    "content": "{{#groupedmanytoonerelations}}\n\n{{#first}}// Grouped Relations{{/first}}\n{{#isPureManyToMany}}\n    // TODO This is a pure ManyToMany relation (delete me and decide owner side)\n{{/isPureManyToMany}}\n{{#comment}}\n    {{implComment}}\n{{/comment}}\nrelationship {{relationType}} {\n{{#relations}}\n    {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}\n{{/relations}}\n}\n{{/groupedmanytoonerelations}}\n"
  },
  {
    "path": "src/main/resources/mustache/groupedonetoonerelations.mustache",
    "content": "{{#groupedonetoonerelations}}\n{{#first}}// Grouped Relations{{/first}}\n{{#isPureManyToMany}}\n    // TODO This is a pure ManyToMany relation (delete me and decide owner side)\n{{/isPureManyToMany}}\n{{#comment}}\n    {{implComment}}\n{{/comment}}\nrelationship {{relationType}} {\n{{#relations}}\n    {{^value.hasComments}}\n    {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n    {{#value.hasComments}}\n        {{#value.ownerDocComment}}\n            {{value.ownerDocComment}}\n        {{/value.ownerDocComment}}\n        {{value.ownerEntityName}}{{value.ownerConfig}} to\n        {{#value.inverseDocComment}}\n            {{value.inverseDocComment}}\n        {{/value.inverseDocComment}}\n        {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n{{/relations}}\n}\n{{/groupedonetoonerelations}}\n"
  },
  {
    "path": "src/main/resources/mustache/manytomanyrelations.mustache",
    "content": "{{#manytomanyrelations}}\n{{#first}}// many-to-many Relations{{/first}}\n{{#value.isPureManyToMany}}\n// TODO This is a pure ManyToMany relation (delete me and decide owner side)\n{{/value.isPureManyToMany}}\n{{#value.comment}}\n{{value.implComment}}\n{{/value.comment}}\nrelationship {{value.type}} {\n    {{^value.hasComments}}\n    {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n    {{#value.hasComments}}\n    {{#value.ownerDocComment}}\n    {{value.ownerDocComment}}\n    {{/value.ownerDocComment}}\n    {{value.ownerEntityName}}{{value.ownerConfig}} to\n    {{#value.inverseDocComment}}\n    {{value.inverseDocComment}}\n    {{/value.inverseDocComment}}\n    {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n}\n{{^last}}{{/last}}\n{{/manytomanyrelations}}\n"
  },
  {
    "path": "src/main/resources/mustache/manytoonerelations.mustache",
    "content": "{{#manytoonerelations}}\n    {{#first}}//many-to-one Relations{{/first}}\n    {{#value.isPureManyToMany}}\n        // TODO This is a pure ManyToMany relation (delete me and decide owner side)\n    {{/value.isPureManyToMany}}\n    {{#value.comment}}\n        {{value.implComment}}\n    {{/value.comment}}\n    relationship {{value.type}} {\n    {{^value.hasComments}}\n        {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n    {{#value.hasComments}}\n        {{#value.ownerDocComment}}\n            {{value.ownerDocComment}}\n        {{/value.ownerDocComment}}\n        {{value.ownerEntityName}}{{value.ownerConfig}} to\n        {{#value.inverseDocComment}}\n            {{value.inverseDocComment}}\n        {{/value.inverseDocComment}}\n        {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n    }\n    {{^last}}{{/last}}\n{{/manytoonerelations}}\n"
  },
  {
    "path": "src/main/resources/mustache/onetoonerelations.mustache",
    "content": "{{#onetoonerelations}}\n    {{#first}}//one-to-one Relations{{/first}}\n    {{#value.isPureManyToMany}}\n        // TODO This is a pure ManyToMany relation (delete me and decide owner side)\n    {{/value.isPureManyToMany}}\n    {{#value.comment}}\n        {{value.implComment}}\n    {{/value.comment}}\n    relationship {{value.type}} {\n    {{^value.hasComments}}\n        {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n    {{#value.hasComments}}\n        {{#value.ownerDocComment}}\n            {{value.ownerDocComment}}\n        {{/value.ownerDocComment}}\n        {{value.ownerEntityName}}{{value.ownerConfig}} to\n        {{#value.inverseDocComment}}\n            {{value.inverseDocComment}}\n        {{/value.inverseDocComment}}\n        {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n    }\n    {{^last}}{{/last}}\n{{/onetoonerelations}}\n"
  },
  {
    "path": "src/main/resources/mustache/options.mustache",
    "content": "{{#options}}\n{{#first}}// Options{{/first}}\n{{value}}\n{{/options}}\n"
  },
  {
    "path": "src/main/resources/mustache/relations.mustache",
    "content": "{{#relations}}\n{{#first}}// Relations{{/first}}\n{{#value.isPureManyToMany}}\n// TODO This is a pure ManyToMany relation (delete me and decide owner side)\n{{/value.isPureManyToMany}}\n{{#value.comment}}\n{{value.implComment}}\n{{/value.comment}}\nrelationship {{value.type}} {\n    {{^value.hasComments}}\n    {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n    {{#value.hasComments}}\n    {{#value.ownerDocComment}}\n    {{value.ownerDocComment}}\n    {{/value.ownerDocComment}}\n    {{value.ownerEntityName}}{{value.ownerConfig}} to\n    {{#value.inverseDocComment}}\n    {{value.inverseDocComment}}\n    {{/value.inverseDocComment}}\n    {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n}\n{{^last}}{{/last}}\n{{/relations}}\n"
  },
  {
    "path": "src/main/resources/mustache/views.mustache",
    "content": "{{#views}}\n{{^value.isPureManyToMany}}\n{{#value.comment}}\n{{value.docComment}}\n{{/value.comment}}\n{{#value.isReadOnly}}\n@readOnly\n{{/value.isReadOnly}}\n{{value.type}} {{value.name}}{{value.tableName}} {\n{{#value.filteredFields}}\n{{#value.comment}}\n    {{value.docComment}}\n{{/value.comment}}\n    {{value.name}} {{value.typeName}}{{value.constraints}}{{^last}},{{/last}}\n{{/value.filteredFields}}\n}\n{{^last}}{{/last}}\n{{/value.isPureManyToMany}}\n{{/views}}\n{{^views}}\n// No views were found for which JDL is to be generated. Please review console logs\n{{/views}}\n"
  },
  {
    "path": "src/main/resources/mustache/viewsrelations.mustache",
    "content": "{{#viewsrelations}}\n{{#first}}// Relations{{/first}}\n{{#value.isPureManyToMany}}\n// TODO This is a pure ManyToMany relation (delete me and decide owner side)\n{{/value.isPureManyToMany}}\n{{#value.comment}}\n{{value.implComment}}\n{{/value.comment}}\nrelationship {{value.type}} {\n    {{^value.hasComments}}\n    {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n    {{#value.hasComments}}\n    {{#value.ownerDocComment}}\n    {{value.ownerDocComment}}\n    {{/value.ownerDocComment}}\n    {{value.ownerEntityName}}{{value.ownerConfig}} to\n    {{#value.inverseDocComment}}\n    {{value.inverseDocComment}}\n    {{/value.inverseDocComment}}\n    {{value.inverseSideEntityName}}{{value.inverseConfig}}\n    {{/value.hasComments}}\n}\n{{^last}}{{/last}}\n{{/viewsrelations}}\n"
  },
  {
    "path": "src/main/resources/reserved/keywords.json",
    "content": "{\n    \"java\": [\n        \"ABSTRACT\",\n        \"CONTINUE\",\n        \"FOR\",\n        \"NEW\",\n        \"SWITCH\",\n        \"ASSERT\",\n        \"DEFAULT\",\n        \"GOTO\",\n        \"PACKAGE\",\n        \"SYNCHRONIZED\",\n        \"BOOLEAN\",\n        \"DO\",\n        \"IF\",\n        \"PRIVATE\",\n        \"THIS\",\n        \"BREAK\",\n        \"DOUBLE\",\n        \"IMPLEMENTS\",\n        \"PROTECTED\",\n        \"THROW\",\n        \"BYTE\",\n        \"ELSE\",\n        \"IMPORT\",\n        \"PUBLIC\",\n        \"THROWS\",\n        \"CASE\",\n        \"ENUM\",\n        \"INSTANCEOF\",\n        \"RETURN\",\n        \"TRANSIENT\",\n        \"CATCH\",\n        \"EXTENDS\",\n        \"INT\",\n        \"SHORT\",\n        \"TRY\",\n        \"CHAR\",\n        \"FINAL\",\n        \"INTERFACE\",\n        \"STATIC\",\n        \"VOID\",\n        \"CLASS\",\n        \"FINALLY\",\n        \"LONG\",\n        \"STRICTFP\",\n        \"VOLATILE\",\n        \"CONST\",\n        \"FLOAT\",\n        \"NATIVE\",\n        \"SUPER\",\n        \"WHILE\"\n    ],\n    \"jhipster\": [\n        \"ACCOUNT\",\n        \"ACTIVATE\",\n        \"AUDITS\",\n        \"CONFIGURATION\",\n        \"DOCS\",\n        \"HEALTH\",\n        \"LOGS\",\n        \"METRICS\",\n        \"PASSWORD\",\n        \"REGISTER\",\n        \"RESET\",\n        \"SESSIONS\",\n        \"SETTINGS\",\n        \"TEST\",\n        \"EVENTMANAGER\",\n        \"PRINCIPAL\",\n        \"ENTITY\",\n        \"RESULT\"\n    ],\n    \"angular\": [\n        \"CLASS\",\n        \"NODENAME\",\n        \"NODETYPE\",\n        \"COMPONENT\",\n        \"SUBSCRIPTION\",\n        \"RESPONSE\",\n        \"OBSERVABLE\",\n        \"INJECTABLE\",\n        \"HTTP\",\n        \"ROUTER\"\n    ],\n    \"typescript\": [\n        \"BREAK\",\n        \"CASE\",\n        \"CATCH\",\n        \"CLASS\",\n        \"CONST\",\n        \"CONSTRUCTOR\",\n        \"CONTINUE\",\n        \"DEBUGGER\",\n        \"DEFAULT\",\n        \"DELETE\",\n        \"DO\",\n        \"ELSE\",\n        \"ENUM\",\n        \"EXPORT\",\n        \"EXTENDS\",\n        \"FALSE\",\n        \"FINALLY\",\n        \"FOR\",\n        \"FUNCTION\",\n        \"IF\",\n        \"IMPORT\",\n        \"IN\",\n        \"INSTANCEOF\",\n        \"NEW\",\n        \"NULL\",\n        \"RETURN\",\n        \"SUPER\",\n        \"SWITCH\",\n        \"THIS\",\n        \"THROW\",\n        \"TRUE\",\n        \"TRY\",\n        \"TYPEOF\",\n        \"VAR\",\n        \"VOID\",\n        \"WHILE\",\n        \"WITH\",\n        \"IMPLEMENTS\",\n        \"INTERFACE\",\n        \"LET\",\n        \"PACKAGE\",\n        \"PRIVATE\",\n        \"PROTECTED\",\n        \"PUBLIC\",\n        \"STATIC\",\n        \"YIELD\"\n    ]\n}\n"
  },
  {
    "path": "src/main/resources/sql/mysql_mariadb-getAllTableInformation.sql",
    "content": "select t.table_schema,\n       t.table_name,\n       case\n           when v.is_updatable='NO' then false\n           else true\n           end as is_updatable,\n       case\n           when t.table_type='VIEW' and t.table_comment='VIEW' then 'view'\n           else t.table_comment\n       end as comment,\n      t.table_type\nfrom information_schema.tables t\nleft join information_schema.views v on v.table_schema=t.table_schema\n                                    and v.table_name=t.table_name\nwhere t.table_schema=:schemaName\norder by t.table_schema,\n         v.is_updatable,\n         t.table_name;\n"
  },
  {
    "path": "src/main/resources/sql/mysql_mariadb-getAllTableRelationInformation.sql",
    "content": "select kku.constraint_name,\n       kku.table_schema,\n       kku.table_name,\n       kku.column_name,\n       kku.referenced_table_schema as foreign_table_schema,\n       kku.referenced_table_name   as foreign_table_name,\n       kku.referenced_column_name  as foreign_column_name\nfrom information_schema.key_column_usage kku\nwhere kku.referenced_table_schema=:schemaName and kku.referenced_table_name is not null\norder by kku.table_name,\n         kku.column_name;\n"
  },
  {
    "path": "src/main/resources/sql/mysql_mariadb-getFullColumnInformationOfTable.sql",
    "content": "select\n    c.table_schema,\n    c.table_name,\n    c.column_name,\n    case\n        when c.character_maximum_length is null then c.data_type\n        else concat(c.data_type, '(', c.character_maximum_length, ')')\n    end as data_type,\n    c.data_type,\n    c.column_default,\n    c.is_nullable,\n    c.column_comment comment,\n    c.column_key 'key',\n    c.ordinal_position\nfrom information_schema.columns c\nwhere c.table_schema=:schemaName\n  and c.table_name=:tableName\norder by c.ordinal_position;\n"
  },
  {
    "path": "src/main/resources/sql/oracle-getAllTableInformation.sql",
    "content": "select o.OWNER       as schema,\n       o.OBJECT_NAME as table_name,\n       case\n           WHEN v.READ_ONLY = 'Y' THEN 'NO'\n           when v.READ_ONLY = 'N' or v.READ_ONLY is null THEN 'YES'\n           END       as is_updatable,\n       case\n           when (o.OBJECT_TYPE = 'VIEW' and tc.COMMENTS is null) then 'view'\n           else tc.COMMENTS\n           end          \"comment\",\n       case o.OBJECT_TYPE\n           when 'VIEW' then 'VIEW'\n           when 'TABLE' then 'BASE TABLE'\n           end          table_type\nfrom ALL_OBJECTS o\n         LEFT JOIN ALL_TABLES t\n                   on (o.OWNER = t.OWNER and o.OBJECT_NAME = t.TABLE_NAME and o.OBJECT_TYPE = 'TABLE' AND\n                       t.NESTED = 'NO')\n         LEFT JOIN ALL_VIEWS v on (o.OWNER = v.OWNER and o.OBJECT_NAME = v.VIEW_NAME and o.OBJECT_TYPE = 'VIEW')\n         LEFT JOIN ALL_TAB_COMMENTS tc\n                   ON (o.OWNER = tc.OWNER AND\n                       o.OBJECT_NAME = tc.TABLE_NAME AND\n                       o.OBJECT_TYPE = tc.TABLE_TYPE)\nWHERE o.owner =:schemaName\n  and (o.OBJECT_TYPE = 'VIEW'\n    or o.OBJECT_TYPE = 'TABLE')\norder by t.OWNER, is_updatable, o.OBJECT_NAME\n"
  },
  {
    "path": "src/main/resources/sql/oracle-getAllTableRelationInformation.sql",
    "content": "SELECT a.constraint_name,\n       c.owner              as table_schema,\n       a.table_name,\n       LOWER(a.column_name) as column_name,\n       -- referenced pk\n       c_pk.OWNER              foreign_table_schema,\n       c_pk.table_name         foreign_table_name,\n       b.COLUMN_NAME           foreign_column_name\nFROM all_cons_columns a\n         JOIN all_constraints c ON a.owner = c.owner\n    AND a.constraint_name = c.constraint_name\n         JOIN all_constraints c_pk ON c.r_owner = c_pk.owner\n    AND c.r_constraint_name = c_pk.constraint_name\n         JOIN all_cons_columns b ON b.OWNER = c_pk.OWNER\n    AND b.constraint_name = c_pk.constraint_name\nWHERE c.constraint_type = 'R'\n  AND A.OWNER =:schemaName\n"
  },
  {
    "path": "src/main/resources/sql/oracle-getFullColumnInformationOfTable.sql",
    "content": "select a.OWNER              as                                                      table_schema,\n       a.TABLE_NAME,\n       LOWER(a.COLUMN_NAME) as                                                      column_name,\n       a.CHAR_LENGTH,\n\n       case\n           -- enum\n           when (select pcc.COLUMN_NAME\n                 from all_constraints pc,\n                      all_cons_columns pcc\n                 where pcc.column_name = a.column_name\n                   and pcc.constraint_name = pc.constraint_name\n                   and pc.constraint_type in ('C')\n                   and lower(pc.SEARCH_CONDITION_VC) like '%in%'\n                   and pcc.owner = upper(a.OWNER)\n                   and pcc.table_name = upper(a.TABLE_NAME)) is not null then 'enum'\n\n           -- NUMBER\n           when a.data_type = 'NUMBER' and a.DATA_PRECISION > 0 and a.DATA_SCALE > 0\n               then 'NUMBER' || '(' || a.DATA_PRECISION || ',' || a.DATA_SCALE || ')'\n           when a.data_type = 'NUMBER' and a.DATA_PRECISION > 0\n               then 'NUMBER' || '(' || a.DATA_PRECISION || ')'\n\n           -- CHAR, VARCHAR2, NCHAR, NVARCHAR2\n           when (a.data_type in ('CHAR', 'VARCHAR2', 'NCHAR', 'NVARCHAR2')) and a.CHAR_LENGTH > 0\n               then a.data_type || '(' || a.CHAR_LENGTH || ')'\n\n           -- FLOAT\n           when a.data_type = 'FLOAT' and a.DATA_PRECISION > 0\n               then a.data_type || '(' || a.DATA_PRECISION || ')'\n\n           else a.DATA_TYPE\n           end                                                                      data_type,\n\n       null                 as                                                      column_default,\n       DECODE(a.NULLABLE, 'Y', 'YES', 'N', 'NO')                                    is_nullable,\n       c.COMMENTS           as                                                      \"COMMENT\",\n       DECODE((select pc.CONSTRAINT_TYPE\n               from all_constraints pc,\n                    all_cons_columns pcc\n               where pcc.column_name = a.column_name\n                 and pcc.constraint_name = pc.constraint_name\n                 and pc.constraint_type in ('P', 'U')\n                 and pcc.owner = upper(a.OWNER)\n                 and pcc.table_name = upper(a.TABLE_NAME)), 'P', 'PRI', 'U', 'UNI') KEY,\n       a.COLUMN_ID          as                                                      ordinal_position\n\nfrom all_tab_columns a,\n     ALL_TAB_COMMENTS b,\n     ALL_COL_COMMENTS c\n\nWHERE a.OWNER =:schemaName\n  AND A.TABLE_NAME =:tableName\n  AND A.OWNER = B.OWNER\n  AND A.OWNER = c.OWNER\n  AND A.TABLE_NAME = B.TABLE_NAME\n  AND A.TABLE_NAME = c.TABLE_NAME\n  AND A.COLUMN_NAME = c.COLUMN_NAME\nORDER BY a.COLUMN_ID\n"
  },
  {
    "path": "src/main/resources/sql/postgresql-getAllTableInformation.sql",
    "content": "with w_tables as (\n  select t.table_schema,\n         t.table_name,\n         t.is_insertable_into as is_updatable,\n         obj_description(c.oid, 'pg_class') as table_comment,\n         t.table_type\n  from information_schema.tables t\n  join pg_catalog.pg_class c on c.oid = cast(concat(t.table_schema, '.', t.table_name) as regclass)\n  where t.table_schema=:schemaName\n  order by t.table_schema,\n           t.table_type,\n           t.table_name\n ) select w.*,\n          case\n              when w.table_type='VIEW' and w.table_comment is null then 'view'\n              else w.table_comment\n          end as comment\n   from w_tables w;\n"
  },
  {
    "path": "src/main/resources/sql/postgresql-getAllTableRelationInformation.sql",
    "content": "select tc.constraint_name,\n       tc.table_schema,\n       tc.table_name,\n       kcu.column_name,\n       ccu.table_schema as foreign_table_schema,\n       ccu.table_name   as foreign_table_name,\n       ccu.column_name  as foreign_column_name\nfrom information_schema.table_constraints as tc\njoin information_schema.key_column_usage as kcu on tc.constraint_name = kcu.constraint_name\n                                        and tc.table_schema = kcu.table_schema\n                                        and tc.table_name=kcu.table_name\njoin information_schema.constraint_column_usage as ccu on ccu.constraint_name = tc.constraint_name\n                                                      and ccu.table_schema = tc.table_schema\nwhere tc.constraint_type = 'FOREIGN KEY'\n  and tc.table_schema=:schemaName\norder by tc.table_schema,\n         tc.table_name,\n         kcu.column_name;\n"
  },
  {
    "path": "src/main/resources/sql/postgresql-getFullColumnInformationOfTable.sql",
    "content": "with w_columns as (\n    select c.table_schema,\n           c.table_name,\n           c.column_name,\n           case\n               when c.data_type='USER-DEFINED' then 'enum('||c.udt_name||')'\n               when c.character_maximum_length is null then c.data_type\n               else c.data_type || '(' || c.character_maximum_length || ')'\n           end as data_type,\n           c.column_default,\n           case\n               when vsc.is_nullable is null then c.is_nullable\n               else vsc.is_nullable\n           end as is_nullable,\n           pg_catalog.col_description(cl.oid, c.ordinal_position) as comment,\n           c.ordinal_position\n    from information_schema.columns c\n    join pg_catalog.pg_class cl on  cl.oid=concat(c.table_schema, '.', c.table_name)::regclass::oid\n    left join information_schema.view_column_usage vcu on vcu.table_schema=c.table_schema\n                                                      and vcu.view_name=c.table_name\n                                                      and vcu.column_name=c.column_name\n    left join information_schema.columns vsc on vsc.table_schema=vcu.table_schema\n                                            and vsc.table_name=vcu.table_name\n                                            and vsc.column_name=vcu.column_name\n    where c.table_schema=:schemaName\n    order by c.table_schema,\n             c.table_name,\n             c.ordinal_position\n), w_constraints as (\n    select distinct -- Duplicates come from joining information_schema.view_column_usage.  Not sure it this is even useful.\n           c.table_schema,\n           c.table_name,\n           c.column_name,\n           left(tc.constraint_type,3) as key\n    from information_schema.columns c\n    join information_schema.constraint_column_usage cu on cu.column_name = c.column_name\n    join information_schema.table_constraints tc on tc.table_schema=c.table_schema\n                                                and tc.table_name=c.table_name\n                                                and cu.constraint_name = tc.constraint_name\n                                                and tc.constraint_type in ('UNIQUE', 'PRIMARY KEY')\n    where c.table_schema=:schemaName\n    order by c.table_schema,\n             c.table_name,\n             c.column_name\n) select distinct -- Duplicates come from joining information_schema.view_column_usage.  Not sure it this is even useful.\n         cd.table_schema,\n         cd.table_name,\n         cd.column_name,\n         cd.data_type,\n         cd.column_default,\n         cd.is_nullable,\n         cd.comment,\n         cc.key,\n         cd.ordinal_position\nfrom w_columns cd\nleft join w_constraints cc on cc.table_schema=cd.table_schema\n                          and cc.table_name=cd.table_name\n                          and cc.column_name=cd.column_name\nwhere cd.table_schema=:schemaName\n  and cd.table_name=:tableName\norder by cd.table_schema,\n         cd.table_name,\n         cd.ordinal_position;\n"
  },
  {
    "path": "src/main/resources/sql/sqlserver-getAllTableInformation.sql",
    "content": "WITH w_tables AS (\nSELECT\n    t.TABLE_SCHEMA,\n    t.TABLE_NAME,\n    t.TABLE_TYPE,\n    CASE\n        WHEN t.TABLE_TYPE = 'BASE TABLE' THEN 1\n        ELSE 0\n    END AS updateable,\n    ep.value AS table_comment\nFROM\n    INFORMATION_SCHEMA.TABLES t\nLEFT JOIN\n    sys.tables st ON st.name = t.TABLE_NAME\nLEFT JOIN\n    sys.extended_properties ep ON ep.major_id = st.object_id AND ep.minor_id = 0 AND ep.name = 'MS_Description'\nWHERE\n    t.TABLE_SCHEMA = 'dbo'\n--ORDER BY\n--    t.TABLE_SCHEMA,\n--    t.TABLE_TYPE,\n--    t.TABLE_NAME;\n)\nSELECT\n    w.*,\n    CASE\n        WHEN w.TABLE_TYPE = 'VIEW' AND w.table_comment IS NULL THEN 'view'\n        ELSE w.table_comment\n    END AS comment\nFROM\n    w_tables w\n--ORDER BY\n--    w.TABLE_SCHEMA, w.TABLE_TYPE, w.TABLE_NAME;\n"
  },
  {
    "path": "src/main/resources/sql/sqlserver-getAllTableRelationInformation.sql",
    "content": "-- create sqlserver-getAllTableRelationInformation.sql for mssql server database using example file postgresql-getAllTableRelationInformation.sql as for postregsql database\nSELECT\n    FK.TABLE_SCHEMA AS table_schema,\n    FK.TABLE_NAME AS table_name,\n    CU.COLUMN_NAME AS column_name,\n    PK.TABLE_SCHEMA AS foreign_table_schema,\n    PK.TABLE_NAME AS foreign_table_name,\n    PT.COLUMN_NAME AS foreign_column_name\nFROM\n    INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C\nINNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK\n    ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME\nINNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK\n    ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME\nINNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU\n    ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME\nINNER JOIN (\n    SELECT\n        i1.TABLE_NAME,\n        i2.COLUMN_NAME\n    FROM\n        INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1\n    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2\n        ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME\n    WHERE\n        i1.CONSTRAINT_TYPE = 'PRIMARY KEY'\n) PT\nON PT.TABLE_NAME = PK.TABLE_NAME\nWHERE\n    FK.TABLE_SCHEMA = :schemaName\n--ORDER BY\n--    FK.TABLE_SCHEMA,\n--    FK.TABLE_NAME;\n"
  },
  {
    "path": "src/main/resources/sql/sqlserver-getFullColumnInformationOfTable.sql",
    "content": "WITH w_columns AS (\n    SELECT\n        c.TABLE_SCHEMA,\n        c.TABLE_NAME,\n        c.COLUMN_NAME,\n        CASE\n            WHEN c.DATA_TYPE = 'USER-DEFINED' THEN 'enum(' + c.COLUMN_NAME + ')'\n            WHEN c.CHARACTER_MAXIMUM_LENGTH IS NULL THEN c.DATA_TYPE\n            ELSE c.DATA_TYPE + '(' + CAST(c.CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + ')'\n        END AS data_type,\n        c.COLUMN_DEFAULT,\n        c.IS_NULLABLE,\n        c.ORDINAL_POSITION\n    FROM\n        INFORMATION_SCHEMA.COLUMNS c\n    WHERE\n        c.TABLE_SCHEMA = :schemaName\n), w_constraints AS (\n    SELECT DISTINCT\n        c.TABLE_SCHEMA,\n        c.TABLE_NAME,\n        c.COLUMN_NAME,\n        LEFT(tc.CONSTRAINT_TYPE, 3) AS keye\n    FROM\n        INFORMATION_SCHEMA.COLUMNS c\n    JOIN\n        INFORMATION_SCHEMA.KEY_COLUMN_USAGE cu ON cu.COLUMN_NAME = c.COLUMN_NAME\n    JOIN\n        INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc ON tc.TABLE_SCHEMA = c.TABLE_SCHEMA\n                                                AND tc.TABLE_NAME = c.TABLE_NAME\n                                                AND cu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME\n                                                AND tc.CONSTRAINT_TYPE IN ('UNIQUE', 'PRIMARY KEY')\n    WHERE\n        c.TABLE_SCHEMA = :schemaName\n\n)\nSELECT * FROM w_columns cd\nleft join w_constraints cc on cc.table_schema=cd.table_schema\n                          and cc.table_name=cd.table_name\n                          and cc.column_name=cd.column_name\nwhere cd.table_schema=:schemaName\n  and cd.table_name=:tableName\n\n\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/AssertUtil.java",
    "content": "package org.blackdread.sqltojava;\n\nimport java.util.Collection;\nimport java.util.Iterator;\nimport org.junit.jupiter.api.Assertions;\n\npublic final class AssertUtil {\n\n    public static void assertFileSame(final Collection<String> expected, final Collection<String> actual) {\n        if (expected.size() != actual.size()) {\n            Assertions.fail(String.format(\"Expected (%s) and actual (%s) size are different\", expected.size(), actual.size()));\n        }\n        if (expected.isEmpty()) {\n            return;\n        }\n\n        final Iterator<String> expectedIterator = expected.iterator();\n        final Iterator<String> actualIterator = actual.iterator();\n        for (int i = 0; i < expected.size(); i++) {\n            final String expectedNext = expectedIterator.next();\n            final String actualNext = actualIterator.next();\n            if (!expected.equals(actual)) {\n                Assertions.fail(String.format(\"Line %d (%s) is different from expected (%s)\", i, actualNext, expectedNext));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/FileUtil.java",
    "content": "package org.blackdread.sqltojava;\n\nimport java.io.IOException;\nimport java.net.URISyntaxException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\nimport java.util.List;\n\npublic final class FileUtil {\n\n    public static List<String> readAllLinesClasspath(final String name) throws URISyntaxException, IOException {\n        return Files.readAllLines(Paths.get(FileUtil.class.getResource(name).toURI()), StandardCharsets.UTF_8);\n    }\n\n    public static List<String> readAllLines(final String name) throws URISyntaxException, IOException {\n        return Files.readAllLines(Paths.get(name), StandardCharsets.UTF_8);\n    }\n    /*\n        try (InputStream in = this.getClass().getResourceAsStream(\"/result/mysql57-expected.jdl\"); InputStreamReader fin = new InputStreamReader(in, StandardCharsets.UTF_8); BufferedReader bufIn = new BufferedReader(fin)) {\n          } catch (Exception e) {\n            throw new RuntimeException(e);\n        }\n     */\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/LoggingExtension.java",
    "content": "package org.blackdread.sqltojava.shared;\n\nimport org.blackdread.sqltojava.shared.interfaces.LoggingTest;\nimport org.junit.jupiter.api.extension.ExtensionContext;\nimport org.junit.jupiter.api.extension.TestInstancePostProcessor;\nimport org.slf4j.LoggerFactory;\n\npublic class LoggingExtension implements TestInstancePostProcessor {\n\n    @Override\n    public void postProcessTestInstance(Object testInstance, ExtensionContext context) {\n        LoggingTest loggingTest = (LoggingTest) testInstance;\n        loggingTest.logger(LoggerFactory.getLogger(context.getTestClass().get()));\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/MainApplicationContextLoader.java",
    "content": "package org.blackdread.sqltojava.shared;\n\nimport org.blackdread.sqltojava.util.AppUtil;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.test.context.SpringBootContextLoader;\n\n/**\n * Using this context loader is the same as what is loaded in main method via\n * the AppUtil.setup method.\n */\npublic class MainApplicationContextLoader extends SpringBootContextLoader {\n\n    @Override\n    protected SpringApplication getSpringApplication() {\n        return AppUtil.setup(super.getSpringApplication());\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/CompareJdlResultsTest.java",
    "content": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport java.io.IOException;\nimport java.net.URISyntaxException;\nimport java.util.List;\nimport org.blackdread.sqltojava.AssertUtil;\nimport org.blackdread.sqltojava.FileUtil;\nimport org.junit.jupiter.api.Test;\n\npublic interface CompareJdlResultsTest extends LoggingTest, EnvironmentTest {\n    @Test\n    default void testFileSame() throws URISyntaxException, IOException {\n        String expectedResultPath = env().getProperty(\"expected.result.path\");\n        String applicationExportPath = env().getProperty(\"application.export.path\");\n        log().info(\"expected.result.path: \" + expectedResultPath);\n        log().info(\"application.export.path: \" + applicationExportPath);\n\n        final List<String> expected = FileUtil.readAllLinesClasspath(expectedResultPath);\n        final List<String> actual = FileUtil.readAllLines(applicationExportPath);\n        AssertUtil.assertFileSame(expected, actual);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/ContainersStartedTest.java",
    "content": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\nimport org.junit.jupiter.api.Test;\n\npublic interface ContainersStartedTest extends JdbcContainerTest {\n    @Test\n    default void testContainerRunning() {\n        boolean test = container().isRunning();\n        String message = String.format(\"Container %s is not running\", container().getDockerImageName());\n        assertTrue(test, message);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/EnvironmentTest.java",
    "content": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport org.springframework.core.env.Environment;\n\npublic interface EnvironmentTest {\n    Environment env();\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/JdbcContainerTest.java",
    "content": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport org.testcontainers.containers.JdbcDatabaseContainer;\n\npublic interface JdbcContainerTest {\n    JdbcDatabaseContainer container();\n    void container(JdbcDatabaseContainer container);\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/LoggingTest.java",
    "content": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport org.slf4j.Logger;\n\npublic interface LoggingTest extends JdbcContainerTest {\n    Logger log();\n    void logger(Logger log);\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/ProfileActiveTest.java",
    "content": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic interface ProfileActiveTest extends EnvironmentTest {\n    @Test\n    default void testCorrectProfileLoaded() {\n        String expectedProfile = env().getProperty(\"expected.profile\");\n        assertNotNull(\"expected.profile should not be null.\", expectedProfile);\n\n        String[] activeProfiles = env().getActiveProfiles();\n        String[] expectedProfiles = new String[] { expectedProfile };\n        Assertions.assertArrayEquals(expectedProfiles, activeProfiles, \"Incorrect profile set\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/tests/BaseJdbcContainerTest.java",
    "content": "package org.blackdread.sqltojava.shared.tests;\n\nimport org.blackdread.sqltojava.shared.LoggingExtension;\nimport org.blackdread.sqltojava.shared.MainApplicationContextLoader;\nimport org.blackdread.sqltojava.shared.interfaces.EnvironmentTest;\nimport org.blackdread.sqltojava.shared.interfaces.JdbcContainerTest;\nimport org.blackdread.sqltojava.shared.interfaces.LoggingTest;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.slf4j.Logger;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.core.env.Environment;\nimport org.springframework.test.context.ContextConfiguration;\nimport org.testcontainers.containers.JdbcDatabaseContainer;\nimport org.testcontainers.containers.MSSQLServerContainer;\nimport org.testcontainers.containers.MariaDBContainer;\nimport org.testcontainers.containers.MySQLContainer;\nimport org.testcontainers.containers.OracleContainer;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Testcontainers;\n\n@Testcontainers\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)\n@ExtendWith(LoggingExtension.class)\n@ContextConfiguration(loader = MainApplicationContextLoader.class)\npublic abstract class BaseJdbcContainerTest implements LoggingTest, EnvironmentTest, JdbcContainerTest {\n\n    private static Logger log;\n    private static JdbcDatabaseContainer container;\n\n    // EnvironmentTest\n    @Autowired\n    private Environment env;\n\n    public static JdbcDatabaseContainer setupContainer(JdbcDatabaseContainer container) {\n        BaseJdbcContainerTest.container = container;\n        System.setProperty(\"spring.datasource.url\", container.getJdbcUrl());\n        System.setProperty(\"spring.datasource.username\", container.getUsername());\n        System.setProperty(\"spring.datasource.password\", container.getPassword());\n        System.setProperty(\"application.database-to-export\", getDefaultSchema(container));\n        return container;\n    }\n\n    /**\n     * Get the default schema based on JdbcDatabaseContainer type.  OracleContainer and MSSQLServerContainer have not been tested.\n     * @param c\n     * @return\n     * @throws IllegalArgumentException\n     */\n    private static String getDefaultSchema(JdbcDatabaseContainer c) throws IllegalArgumentException {\n        //TODO use Pattern matching for switch when out of preview\n        if (c instanceof MySQLContainer || c instanceof MariaDBContainer) {\n            return \"test\";\n        } else if (c instanceof OracleContainer) {\n            return \"TEST\";\n        } else if (c instanceof PostgreSQLContainer) {\n            return \"public\";\n        } else if (c instanceof MSSQLServerContainer) {\n            return \"dbo\";\n        } else {\n            throw new IllegalArgumentException(\"Unrecognized JdbcDatabaseContainer \" + container.getClass());\n        }\n    }\n\n    @Override\n    public Environment env() {\n        return env;\n    }\n\n    // LoggingTest\n    @Override\n    public Logger log() {\n        return log;\n    }\n\n    @Override\n    public void logger(Logger log) {\n        BaseJdbcContainerTest.log = log;\n    }\n\n    // JdbcContainerTest\n    @Override\n    public JdbcDatabaseContainer container() {\n        return container;\n    }\n\n    @Override\n    public void container(JdbcDatabaseContainer container) {\n        BaseJdbcContainerTest.container = container;\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/tests/SqlToJdlTransactionPerTestTest.java",
    "content": "package org.blackdread.sqltojava.shared.tests;\n\nimport static org.assertj.core.api.AssertionsForClassTypes.assertThat;\nimport static org.junit.jupiter.api.Assertions.assertThrows;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\nimport java.sql.SQLException;\nimport java.util.stream.Stream;\nimport liquibase.exception.LiquibaseException;\nimport org.blackdread.sqltojava.service.logic.ExportService;\nimport org.blackdread.sqltojava.service.logic.JdlService;\nimport org.blackdread.sqltojava.shared.interfaces.ProfileActiveTest;\nimport org.blackdread.sqltojava.util.ResourceUtil;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.params.ParameterizedTest;\nimport org.junit.jupiter.params.provider.MethodSource;\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic abstract class SqlToJdlTransactionPerTestTest extends TransactionPerTestTest implements ProfileActiveTest {\n\n    @Autowired\n    private JdlService jdlService;\n\n    @Autowired\n    private ExportService exportService;\n\n    /**\n     * To run a different set, implement this method in subclasses.\n     * @return list of test names to run\n     */\n    private static Stream<String> provideTestNames() {\n        return Stream.of(\n            \"uuid_id_required\",\n            \"all_types\",\n            \"one_to_one\",\n            \"display_field_many_to_one\",\n            \"many_to_one\",\n            \"one_to_one_main_map\",\n            \"parent_child\",\n            \"unique\",\n            \"enum\",\n            \"views\",\n            \"readonly\",\n            \"reflexive_relationship\",\n            \"prune\",\n            \"duplicate_names\"\n        );\n    }\n\n    /**\n     * Clear all caches so each test will generate the correct JDL\n     */\n    @BeforeEach\n    public void checkSchemaEmpty() {\n        evictAllCaches();\n    }\n\n    /**\n     * This method will run a liquibase changeset, generate jdl, compare it to the expected results,\n     * and then rollback to an empty database before running the next test.\n     * @param testName\n     * @throws SQLException\n     * @throws LiquibaseException\n     */\n    @ParameterizedTest\n    @MethodSource(\"provideTestNames\")\n    public void testChangelog(String testName) {\n        testJdl(testName);\n    }\n\n    private void testJdl(String testName) {\n        String activeProfile = env().getActiveProfiles()[0];\n        String pathChangeLogFile = getExpectedLiquibaseChangeset(testName, activeProfile);\n        try {\n            runChangeLogFile(pathChangeLogFile);\n        } catch (SQLException e) {\n            throw new RuntimeException(e);\n        } catch (LiquibaseException e) {\n            throw new RuntimeException(e);\n        }\n\n        String jdlExpected = getExpectedJdl(testName, activeProfile);\n        String jdlActual = exportService.exportString(jdlService.buildEntities());\n        assertThat(jdlActual).isEqualTo(jdlExpected).withFailMessage(\"JDL output did not match expected.\");\n    }\n\n    protected void testJdlException(String testName, Class<RuntimeException> exceptionClass) {\n        Exception exception = assertThrows(\n            exceptionClass,\n            () -> {\n                testJdl(testName);\n            }\n        );\n\n        String expectedMessagePrefix = \"Unsupported jdl type\";\n        String actualMessage = exception.getCause().getMessage();\n\n        assertTrue(actualMessage.startsWith(expectedMessagePrefix), actualMessage);\n    }\n\n    /**\n     * The expected jdl file will first be searched for at /jdl/testName-liquibase-changeset-activeProfile.yaml and then at\n     * /jdl/testName-liquibase-changeset.yaml.  If neither match an error will be thrown.\n     *\n     * @param testName\n     * @param activeProfile\n     * @return\n     */\n    private String getExpectedLiquibaseChangeset(String testName, String activeProfile) {\n        String pathChangesetProfile = String.format(\"/jdl/%s-liquibase-changeset-%s.yaml\", testName, activeProfile);\n        String pathChangesetDefault = String.format(\"/jdl/%s-liquibase-changeset.yaml\", testName);\n        return ResourceUtil.getFirstExistingResourcePath(\"liquibase-changeset.yaml\", pathChangesetProfile, pathChangesetDefault);\n    }\n\n    /**\n     * The expected jdl file will first be searched for at /jdl/testName-expected-activeProfile.jdl and then at\n     * /jdl/testName-expected.jdl.  If neither match an error will be thrown.\n     *\n     * @param testName\n     * @param activeProfile\n     * @return\n     */\n    private String getExpectedJdl(String testName, String activeProfile) {\n        String pathJdlExpectedProfile = String.format(\"/jdl/%s-expected-%s.jdl\", testName, activeProfile);\n        String pathJdlExpectedDefault = String.format(\"/jdl/%s-expected.jdl\", testName);\n        String pathJdlExpected = ResourceUtil.getFirstExistingResourcePath(\"expected.jdl\", pathJdlExpectedProfile, pathJdlExpectedDefault);\n        return pathToString(pathJdlExpected);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/tests/TransactionPerTestTest.java",
    "content": "package org.blackdread.sqltojava.shared.tests;\n\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.sql.Connection;\nimport java.sql.SQLException;\nimport javax.sql.DataSource;\nimport liquibase.Contexts;\nimport liquibase.LabelExpression;\nimport liquibase.Liquibase;\nimport liquibase.database.Database;\nimport liquibase.database.DatabaseFactory;\nimport liquibase.database.jvm.JdbcConnection;\nimport liquibase.exception.LiquibaseException;\nimport liquibase.resource.ClassLoaderResourceAccessor;\nimport liquibase.resource.ResourceAccessor;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.AfterEach;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.cache.CacheManager;\nimport org.springframework.jdbc.datasource.DataSourceUtils;\nimport org.springframework.test.annotation.DirtiesContext;\n\n@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)\npublic abstract class TransactionPerTestTest extends BaseJdbcContainerTest {\n\n    private static final Logger log = LoggerFactory.getLogger(TransactionPerTestTest.class);\n    private static final String rollbackTag = \"0.0.0\";\n    private static final Contexts contexts = new Contexts(\"integration-test\");\n    private static final LabelExpression labelExpression = new LabelExpression();\n    private static final ResourceAccessor RESOURCE_ACCESSOR = new ClassLoaderResourceAccessor();\n    private Liquibase liquibase;\n\n    @Autowired\n    private DataSource dataSource;\n\n    @Autowired\n    CacheManager cacheManager;\n\n    private Connection connection;\n\n    public DataSource dataSource() {\n        return this.dataSource;\n    }\n\n    @AfterEach\n    public void rollback() throws LiquibaseException {\n        if (liquibase != null) {\n            rollbackToEmpty();\n            liquibase.close();\n        }\n    }\n\n    @AfterAll\n    public static void cleanup() {}\n\n    protected String pathToString(String path) {\n        String content = null;\n        try {\n            content = Files.readString(Path.of(getClass().getResource(path).toURI()));\n        } catch (Exception e) {}\n        return content;\n    }\n\n    protected void evictAllCaches() {\n        log.info(\"Clearing all caches\");\n        cacheManager.getCacheNames().stream().forEach(cacheName -> cacheManager.getCache(cacheName).clear());\n    }\n\n    private Database database(DataSource dataSource) throws LiquibaseException {\n        this.connection = DataSourceUtils.getConnection(dataSource);\n        Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(this.connection));\n        return database;\n    }\n\n    protected void runChangeLogFile(String pathChangeLogFile) throws SQLException, LiquibaseException {\n        liquibase = createLiquibase(pathChangeLogFile);\n        liquibase.update(contexts, labelExpression);\n    }\n\n    private Liquibase createLiquibase(String pathChangeLogFile) throws SQLException, LiquibaseException {\n        return new Liquibase(pathChangeLogFile, RESOURCE_ACCESSOR, database(dataSource));\n    }\n\n    private void rollbackToEmpty() throws LiquibaseException {\n        liquibase.rollback(rollbackTag, contexts);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mssql/MssqlSql2019Test.java",
    "content": "package org.blackdread.sqltojava.test.db.mssql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Disabled;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.MSSQLServerContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass MssqlSql2019Test extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final MSSQLServerContainer MSSQL_CONTAINER = new MSSQLServerContainer(\n        DockerImageName.parse(\"mcr.microsoft.com/mssql/server\").withTag(\"2019-latest\")\n    )\n        .acceptLicense();\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    protected static void setEnv(String name, String value) {\n        env.set(name, value);\n    }\n\n    @BeforeAll\n    public static void setup() {\n        setEnv(\"expected.profile\", \"sqlserver\");\n        setupContainer(MSSQL_CONTAINER);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mysql/MariaDBLatestTest.java",
    "content": "package org.blackdread.sqltojava.test.db.mysql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.MariaDBContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass MariaDBLatestTest extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final MariaDBContainer MARIA_DB_CONTAINER = new MariaDBContainer(DockerImageName.parse(\"mariadb:latest\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"mariadb\");\n        setupContainer(MARIA_DB_CONTAINER);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mysql/Mysql57Test.java",
    "content": "package org.blackdread.sqltojava.test.db.mysql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.MySQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass Mysql57Test extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final MySQLContainer MYSQL_CONTAINER = new MySQLContainer(DockerImageName.parse(\"mysql:5.7\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"mysql\");\n        setupContainer(MYSQL_CONTAINER);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mysql/Mysql8Test.java",
    "content": "package org.blackdread.sqltojava.test.db.mysql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.MySQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass Mysql8Test extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final MySQLContainer MYSQL_CONTAINER = new MySQLContainer(DockerImageName.parse(\"mysql:8.0\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"mysql\");\n        setupContainer(MYSQL_CONTAINER);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mysql/Mysql9Test.java",
    "content": "package org.blackdread.sqltojava.test.db.mysql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Disabled;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.MySQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@Disabled(\"Fails to connect to the container\")\n@ExtendWith(SystemStubsExtension.class)\nclass Mysql9Test extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final MySQLContainer MYSQL_CONTAINER = new MySQLContainer(DockerImageName.parse(\"mysql:9\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"mysql\");\n        setupContainer(MYSQL_CONTAINER);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mysql/MysqlLatestTest.java",
    "content": "package org.blackdread.sqltojava.test.db.mysql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Disabled;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.MySQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@Disabled(\"Fails to download the container\")\n@ExtendWith(SystemStubsExtension.class)\nclass MysqlLatestTest extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final MySQLContainer MYSQL_CONTAINER = new MySQLContainer(DockerImageName.parse(\"mysql:latest\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"mysql\");\n        setupContainer(MYSQL_CONTAINER);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/oracle/OracleLatestTest.java",
    "content": "package org.blackdread.sqltojava.test.db.oracle;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.OracleContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass OracleLatestTest extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final OracleContainer ORACLE_CONTAINER = new OracleContainer(DockerImageName.parse(\"gvenzl/oracle-xe:latest\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"oracle\");\n        setupContainer(ORACLE_CONTAINER);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres09Test.java",
    "content": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass Postgres09Test extends SqlToJdlTransactionPerTestTest {\n\n    static String dockerImageName;\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:9\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres10Test.java",
    "content": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass Postgres10Test extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:10-alpine\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres15Test.java",
    "content": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass Postgres15Test extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:15-alpine\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres17Test.java",
    "content": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass Postgres17Test extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:17-alpine\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresAddTableNameJdlTest.java",
    "content": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass PostgresAddTableNameJdlTest extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:latest\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        env.set(\"application.add_table_name_jdl\", \"true\");\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n\n    private static Stream<String> provideTestNames() {\n        return Stream.of(\"table_name\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresDatabaseObjectPrefixTest.java",
    "content": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass PostgresDatabaseObjectPrefixTest extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:latest\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n\n    private static Stream<String> provideTestNames() {\n        return Stream.of(\"prefix\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresLatestTest.java",
    "content": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass PostgresLatestTest extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:latest\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n\n    private static Stream<String> provideTestNames_() {\n        return Stream.of(\"one_to_one\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresOverrideJdlTypeTest.java",
    "content": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.test.context.TestPropertySource;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\n@TestPropertySource(properties = \"application.jdl-type-overrides.numeric=FLOAT\")\nclass PostgresOverrideJdlTypeTest extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:latest\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n\n    private static Stream<String> provideTestNames() {\n        return Stream.of(\"override_jdl_types\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/DatabaseObjectPrefixTest.java",
    "content": "package org.blackdread.sqltojava.test.general;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.util.List;\nimport org.blackdread.sqltojava.util.JdlUtils;\nimport org.junit.jupiter.api.Test;\n\npublic class DatabaseObjectPrefixTest {\n\n    @Test\n    public void testPrefix() {\n        String name = JdlUtils.getEntityName(\"t_test\", List.of(\"t_\"));\n        assertThat(name).isEqualTo(\"Test\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/MustacheTest.java",
    "content": "package org.blackdread.sqltojava.test.general;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\nimport java.util.*;\nimport java.util.stream.Collectors;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\nimport org.blackdread.sqltojava.config.UndefinedJdlTypeHandlingEnum;\nimport org.blackdread.sqltojava.entity.JdlFieldEnum;\nimport org.blackdread.sqltojava.entity.JdlRelation;\nimport org.blackdread.sqltojava.entity.RelationType;\nimport org.blackdread.sqltojava.entity.impl.JdlEntityImpl;\nimport org.blackdread.sqltojava.entity.impl.JdlFieldImpl;\nimport org.blackdread.sqltojava.entity.impl.JdlRelationImpl;\nimport org.blackdread.sqltojava.service.logic.MustacheService;\nimport org.blackdread.sqltojava.util.JdlUtils;\nimport org.blackdread.sqltojava.view.impl.JdlRelationViewImpl;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.TestConfiguration;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.test.context.ContextConfiguration;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@ContextConfiguration(classes = { MustacheTest.MustacheServiceTestContextConfiguration.class })\npublic class MustacheTest {\n\n    @TestConfiguration\n    static class MustacheServiceTestContextConfiguration {\n\n        @Bean\n        public MustacheService mustacheService() {\n            ApplicationProperties properties = mock(ApplicationProperties.class);\n            when(properties.getUndefinedTypeHandling()).thenReturn(UndefinedJdlTypeHandlingEnum.UNSUPPORTED);\n            return new MustacheService(properties);\n        }\n    }\n\n    @Autowired\n    private MustacheService mustacheService;\n\n    JdlFieldImpl p = new JdlFieldImpl(JdlFieldEnum.UUID, \"id\", true, null, null, null, null, null, false, false, true);\n    JdlFieldImpl f = new JdlFieldImpl(JdlFieldEnum.STRING, \"abrev\", true, null, 2, 6, null, null, false, true, false);\n    JdlEntityImpl b = new JdlEntityImpl(\"B\", null, List.of(p, f), \"Entity B comment\", false, false, false, Collections.emptyList());\n    JdlRelationImpl relationWithComments = new JdlRelationViewImpl(\n        RelationType.ManyToOne,\n        true,\n        true,\n        false,\n        \"A\",\n        \"B\",\n        \"a\",\n        null,\n        \"Owner comment\",\n        \"Inverse comment\",\n        \"b\",\n        null,\n        \"Relation comment\"\n    );\n\n    JdlRelationImpl relationWithoutComments = new JdlRelationViewImpl(\n        RelationType.ManyToOne,\n        true,\n        true,\n        false,\n        \"A\",\n        \"B\",\n        \"a\",\n        null,\n        null,\n        null,\n        \"b\",\n        null,\n        null\n    );\n\n    JdlRelationImpl relationWithoutBirectional = new JdlRelationViewImpl(\n        RelationType.ManyToOne,\n        false,\n        true,\n        false,\n        \"A\",\n        \"B\",\n        \"a\",\n        null,\n        null,\n        null,\n        \"b\",\n        null,\n        null\n    );\n\n    JdlEntityImpl a = new JdlEntityImpl(\n        \"A\",\n        null,\n        List.of(p, f),\n        \"Entity A comment\",\n        false,\n        false,\n        false,\n        List.of(relationWithoutComments)\n    );\n\n    @Test\n    public void testEntity() {\n        String expected =\n            \"\"\"\n            /** Entity A comment */\n            entity A {\n                id UUID,\n                abrev String required unique minlength(2) maxlength(6)\n            }\n            \"\"\";\n        Map<String, Object> context = new HashMap<>();\n        context.put(\"entities\", List.of(a));\n        String result = mustacheService.executeTemplate(\"entities\", context);\n        assertThat(result).isEqualTo(expected);\n    }\n\n    @Test\n    public void testRelation() {\n        String expected =\n            \"\"\"\n            // Relations\n            // Relation comment\n            relationship ManyToOne {\n                /** Owner comment */\n                A{a required} to\n                /** Inverse comment */\n                B{b}\n            }\n            \"\"\";\n        String result = mustacheService.executeTemplate(\"relations\", Map.of(\"relations\", List.of(relationWithComments)));\n        assertThat(result).isEqualTo(expected);\n    }\n\n    @Test\n    public void testRelationWithoutComments() {\n        String expected =\n            \"\"\"\n            // Relations\n            relationship ManyToOne {\n                A{a required} to B{b}\n            }\n            \"\"\";\n        String result = mustacheService.executeTemplate(\"relations\", Map.of(\"relations\", List.of(relationWithoutComments)));\n        assertThat(result).isEqualTo(expected);\n    }\n\n    @Test\n    public void testRelationWithoutBidirectional() {\n        String expected =\n            \"\"\"\n            // Relations\n            relationship ManyToOne {\n                A{a required} to B\n            }\n            \"\"\";\n        String result = mustacheService.executeTemplate(\"relations\", Map.of(\"relations\", List.of(relationWithoutBirectional)));\n        assertThat(result).isEqualTo(expected);\n    }\n\n    @Test\n    public void testEntities() {\n        String expected =\n            \"\"\"\n            /** Entity A comment */\n            entity A {\n                id UUID,\n                abrev String required unique minlength(2) maxlength(6)\n            }\n\n            /** Entity B comment */\n            entity B {\n                id UUID,\n                abrev String required unique minlength(2) maxlength(6)\n            }\n            \"\"\";\n        List<JdlEntityImpl> entities = Arrays.asList(a, b);\n        Map<String, Object> context = new HashMap<>();\n        context.put(\"entities\", entities);\n\n        String result = mustacheService.executeTemplate(\"entities\", context);\n        assertThat(result).isEqualTo(expected);\n    }\n\n    @Test\n    public void testNoEntities() {\n        String expected =\n            \"\"\"\n            // No entities were found for which JDL is to be generated. Please review console logs\n            \"\"\";\n        List<JdlEntityImpl> entities = Collections.emptyList();\n        Map<String, Object> context = new HashMap<>();\n        context.put(\"entities\", entities);\n\n        String result = mustacheService.executeTemplate(\"entities\", context);\n        assertThat(result).isEqualTo(expected);\n    }\n\n    @Test\n    public void testApplication() {\n        String expected =\n            \"\"\"\n                /** Entity A comment */\n                entity A {\n                    id UUID,\n                    abrev String required unique minlength(2) maxlength(6)\n                }\n\n                /** Entity B comment */\n                entity B {\n                    id UUID,\n                    abrev String required unique minlength(2) maxlength(6)\n                }\n\n                // Relations\n                relationship ManyToOne {\n                    A{a required} to B{b}\n                }\n                \"\"\";\n        List<JdlEntityImpl> entities = Arrays.asList(a, b);\n        List<JdlRelation> relations = entities.stream().flatMap(e -> e.getRelations().stream()).collect(Collectors.toList());\n\n        List<String> options = JdlUtils.getOptions();\n\n        Map<String, Object> context = new HashMap<>();\n        context.put(\"entities\", entities);\n        context.put(\"relations\", relations);\n\n        String result = mustacheService.executeTemplate(\"application\", context);\n        assertThat(result).isEqualTo(expected);\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/unsupported/PostgresUndefinedErrorTest.java",
    "content": "package org.blackdread.sqltojava.test.general.unsupported;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.config.UndefinedJdlTypeHandlingEnum;\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.junit.jupiter.params.ParameterizedTest;\nimport org.junit.jupiter.params.provider.MethodSource;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass PostgresUndefinedErrorTest extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:latest\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        env.set(\"application.undefined_type_handling\", UndefinedJdlTypeHandlingEnum.ERROR);\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n\n    @ParameterizedTest\n    @MethodSource(\"provideTestNames\")\n    public void testChangelog(String testName) {\n        testJdlException(testName, RuntimeException.class);\n    }\n\n    private static Stream<String> provideTestNames() {\n        return Stream.of(\"undefined_error\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/unsupported/PostgresUndefinedSkioTest.java",
    "content": "package org.blackdread.sqltojava.test.general.unsupported;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.config.UndefinedJdlTypeHandlingEnum;\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass PostgresUndefinedSkioTest extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:latest\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        env.set(\"application.undefined_type_handling\", UndefinedJdlTypeHandlingEnum.SKIP);\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n\n    private static Stream<String> provideTestNames() {\n        return Stream.of(\"undefined_skip\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/unsupported/PostgresUndefinedUnsupportedTest.java",
    "content": "package org.blackdread.sqltojava.test.general.unsupported;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.config.UndefinedJdlTypeHandlingEnum;\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\nclass PostgresUndefinedUnsupportedTest extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:latest\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        env.set(\"application.undefined_type_handling\", UndefinedJdlTypeHandlingEnum.UNSUPPORTED);\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n\n    private static Stream<String> provideTestNames() {\n        return Stream.of(\"undefined_unsupported\");\n    }\n}\n"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/views/PostgresDatabaseObjectTypesTest.java",
    "content": "package org.blackdread.sqltojava.test.general.views;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTestTest;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.test.context.TestPropertySource;\nimport org.testcontainers.containers.PostgreSQLContainer;\nimport org.testcontainers.junit.jupiter.Container;\nimport org.testcontainers.utility.DockerImageName;\nimport uk.org.webcompere.systemstubs.environment.EnvironmentVariables;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStub;\nimport uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;\n\n@ExtendWith(SystemStubsExtension.class)\n@TestPropertySource(properties = \"application.database_object_types_config=TABLES\")\nclass PostgresDatabaseObjectTypesConfigTest extends SqlToJdlTransactionPerTestTest {\n\n    @Container\n    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(\"postgres:latest\"));\n\n    @SystemStub\n    private static EnvironmentVariables env;\n\n    @BeforeAll\n    public static void setup() {\n        env.set(\"expected.profile\", \"postgresql\");\n        setupContainer(POSTGRE_SQL_CONTAINER);\n    }\n\n    private static Stream<String> provideTestNames() {\n        return Stream.of(\"tables-only\");\n    }\n}\n"
  },
  {
    "path": "src/test/resources/application.yml",
    "content": "spring:\n    datasource:\n        type: com.zaxxer.hikari.HikariDataSource\n        #url: dynamically set based on JdbcDatabaseContainer type\n        #username: dynamically set based on JdbcDatabaseContainer type\n        #password: dynamically set based on JdbcDatabaseContainer type\n        hikari:\n            data-source-properties:\n                cachePrepStmts: true\n                prepStmtCacheSize: 250\n                prepStmtCacheSqlLimit: 2048\n                useServerPrepStmts: true\n    flyway:\n        enabled: false\n\napplication:\n    reserved-keywords: classpath:reserved/keywords.json\n    #database-to-export: dynamically set based on JdbcDatabaseContainer type\n    database-object-prefix:\n        - t_\n        - v_\n    add_table_name_jdl: false\n    undefined_type_handling: ERROR\n    database_object_types_config: ALL # TABLES, ViEWS, ALL\n    render_entities_only: true\n    assume_bidirectional: true\n    ignored-table-names:\n        - databasechangelog\n        - databasechangeloglock\n        - DATABASECHANGELOG\n        - DATABASECHANGELOGLOCK\n        - flyway_schema_history\n        - QRTZ_BLOB_TRIGGERS\n        - QRTZ_CALENDARS\n        - QRTZ_CRON_TRIGGERS\n        - QRTZ_FIRED_TRIGGERS\n        - QRTZ_JOB_DETAILS\n        - QRTZ_LOCKS\n        - QRTZ_PAUSED_TRIGGER_GRPS\n        - QRTZ_SCHEDULER_STATE\n        - QRTZ_SIMPLE_TRIGGERS\n        - QRTZ_SIMPROP_TRIGGERS\n        - QRTZ_TRIGGERS\n        - MSreplication_options\n        - spt_fallback_db\n        - spt_fallback_dev\n        - spt_fallback_usg\n        - spt_monitor\n        - spt_values\n    export:\n        path: ./my-project-jdl.jh\n        type: jdl\n        export-file-structure-type: SEPARATED\n        export-mustache-template-filename-optional:\n"
  },
  {
    "path": "src/test/resources/container-license-acceptance.txt",
    "content": "mcr.microsoft.com/mssql/server:2019-latest\n"
  },
  {
    "path": "src/test/resources/db/changelog/db.changelog-master.yaml",
    "content": "databaseChangeLog:\n    -   changeSet:\n            id: empty\n            author: empty\n            changes:\n                -   tagDatabase:\n                        tag: 0.0.0\n                -   empty: { }\n"
  },
  {
    "path": "src/test/resources/jdl/all_jdl_types-expected.jdl",
    "content": "/** This comment will be taken into account */\nenum EnumType {\n    // But not this one!\n    VALUE1,\n    VALUE2\n}\n\nentity AllType {\n    myString String,\n    myInteger Integer,\n    myLong Long,\n    myBigDecimal BigDecimal,\n    myFloat Float,\n    myDouble Double,\n    myEnum Enum,\n    myBoolean Boolean,\n    myLocalDate LocalDate,\n    myZonedDateTime ZonedDateTime,\n    myInstant Instant,\n    myDuration Duration,\n    myUUID UUID,\n    myBlob Blob,\n    myAnyBlob AnyBlob,\n    myImageBlob ImageBlob,\n    myTextBlob TextBlob\n}\n"
  },
  {
    "path": "src/test/resources/jdl/all_types-expected-mariadb.jdl",
    "content": "/** my table comment */\nentity AllType {\n    myId String required maxlength(25),\n    myInt Integer required,\n    myIntNull Integer,\n    myVarchar50 String required maxlength(50),\n    myVarchar50Null String maxlength(50),\n    /** super varchar 512 */\n    myVarchar512 String required maxlength(512),\n    myTinytext String required maxlength(255),\n    myMediumtext TextBlob required,\n    myLongtext TextBlob required,\n    myText String required maxlength(65535),\n    myChar String required maxlength(5),\n    myDate LocalDate required,\n    myDatetime Instant required,\n    myTimestamp Instant required,\n    myTime String required minlength(8) maxlength(8) pattern(/^(([0-1]\\d)|(2[0-3])):([0-5]\\d):([0-5]\\d)$/),\n    myBigint Long required,\n    myTinyint Boolean required,\n    /** small int comment */\n    mySmallint Integer required,\n    myDecimal BigDecimal required,\n    myDouble Double required,\n    myBit Boolean required,\n    myBool Boolean required,\n    myJson TextBlob required,\n    myTinyblob Blob required,\n    myMediumblob Blob required,\n    myLongblob Blob required,\n    myTinyint8 Boolean required\n}\n\n/** my table comment */\nentity MysqlType {\n    myYear String required pattern(/^-?(\\d+)$/),\n    myMediumint Integer required,\n    myFloat Float required,\n    myEnumSql MyEnumSql required,\n    mySet MySet required,\n    myGeometry String required,\n    /** blob comment */\n    myBlob Blob required\n}\n"
  },
  {
    "path": "src/test/resources/jdl/all_types-expected-mysql.jdl",
    "content": "/** my table comment */\nentity AllType {\n    myId String required maxlength(25),\n    myInt Integer required,\n    myIntNull Integer,\n    myVarchar50 String required maxlength(50),\n    myVarchar50Null String maxlength(50),\n    /** super varchar 512 */\n    myVarchar512 String required maxlength(512),\n    myTinytext String required maxlength(255),\n    myMediumtext TextBlob required,\n    myLongtext TextBlob required,\n    myText String required maxlength(65535),\n    myChar String required maxlength(5),\n    myDate LocalDate required,\n    myDatetime Instant required,\n    myTimestamp Instant required,\n    myTime String required minlength(8) maxlength(8) pattern(/^(([0-1]\\d)|(2[0-3])):([0-5]\\d):([0-5]\\d)$/),\n    myBigint Long required,\n    myTinyint Boolean required,\n    /** small int comment */\n    mySmallint Integer required,\n    myDecimal BigDecimal required,\n    myDouble Double required,\n    myBit Boolean required,\n    myBool Boolean required,\n    myJson String required,\n    myTinyblob Blob required,\n    myMediumblob Blob required,\n    myLongblob Blob required,\n    myTinyint8 Boolean required\n}\n\n/** my table comment */\nentity MysqlType {\n    myYear String required pattern(/^-?(\\d+)$/),\n    myMediumint Integer required,\n    myFloat Float required,\n    myEnumSql MyEnumSql required,\n    mySet MySet required,\n    myGeometry String required,\n    /** blob comment */\n    myBlob Blob required\n}\n"
  },
  {
    "path": "src/test/resources/jdl/all_types-expected-oracle.jdl",
    "content": "/** my table comment */\nentity OracleType {\n    myId String required maxlength(25),\n    myBoolean Integer,\n    myTinyint Integer,\n    myInt Integer,\n    myBigint Long,\n    myFloat Float,\n    myDouble Float,\n    myDecimal Integer,\n    myNumber Integer,\n    /** blob comment */\n    myBlob Blob,\n    myDatetime Instant,\n    myTime LocalDate,\n    myTimestamp Instant,\n    myDate LocalDate,\n    myChar String maxlength(1),\n    myVarchar50 String required maxlength(50),\n    myVarchar50Null String maxlength(50),\n    myNchar String maxlength(1),\n    myNvarchar50 String required maxlength(50),\n    myNvarchar50Null String maxlength(50),\n    myClob Blob,\n    myCurrency Integer,\n    myUuid UUID\n}\n"
  },
  {
    "path": "src/test/resources/jdl/all_types-expected-postgresql.jdl",
    "content": "entity PostgresType {\n    myBoolean Boolean,\n    myDate LocalDate,\n    myTime String minlength(8) maxlength(8) pattern(/^(([0-1]\\d)|(2[0-3])):([0-5]\\d):([0-5]\\d)$/),\n    myTimeWithTimeZone String minlength(8) maxlength(8) pattern(/^(([0-1]\\d)|(2[0-3])):([0-5]\\d):([0-5]\\d)$/),\n    myTimestamp Instant,\n    myTimestampWithTimeZone ZonedDateTime,\n    myReal Float,\n    myDoublePrecision Double,\n    mySmallint Integer,\n    myInteger Integer,\n    myBigint Long,\n    myMoney BigDecimal,\n    myNumeric BigDecimal,\n    myBpchar String maxlength(1),\n    myChar String maxlength(1),\n    myText String,\n    myVarchar String maxlength(255),\n    myBytea Blob,\n    myJson String,\n    myUuid UUID\n}\n"
  },
  {
    "path": "src/test/resources/jdl/all_types-expected-sqlserver.jdl",
    "content": "/** my table comment */\nentity AllType {\n    myId String required maxlength(25),\n    myInt Integer required,\n    myIntNull Integer,\n    myVarchar50 String required maxlength(50),\n    myVarchar50Null String maxlength(50),\n    myVarchar512 String required maxlength(512),\n    myTinytext TextBlob required,\n    myMediumtext TextBlob required,\n    myLongtext TextBlob required,\n    myText TextBlob required,\n    myChar String required maxlength(5),\n    myDate LocalDate required,\n    myDatetime Instant required,\n    myTimestamp Instant required,\n    myTime String required minlength(8) maxlength(8) pattern(/^(([0-1]\\d)|(2[0-3])):([0-5]\\d):([0-5]\\d)$/),\n    myBigint Long required,\n    myTinyint Integer required,\n    mySmallint Integer required,\n    myDecimal BigDecimal required,\n    myDouble Double required,\n    myBit Boolean required,\n    myBool Boolean required,\n    myJson TextBlob required,\n    myTinyblob Blob required,\n    myMediumblob Blob required,\n    myLongblob Blob required,\n    myTinyint8 Integer required\n}\n"
  },
  {
    "path": "src/test/resources/jdl/all_types-liquibase-changeset-sqlserver.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: all_types-create_table_all\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n#          dbms: sqlserver\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: my_id\n                              type: NVARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              defaultValueNumeric: 55\n                              name: my_int\n                              type: INT\n                        - column:\n                              name: my_int_null\n                              type: INT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              defaultValue: default of varchar 50\n                              name: my_varchar_50\n                              type: NVARCHAR(50)\n                        - column:\n                              name: my_varchar_50_null\n                              type: NVARCHAR(50)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_varchar_512\n                              remarks: super varchar 512\n                              type: NVARCHAR(512)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_tinytext\n                              type: NVARCHAR(MAX)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_mediumtext\n                              type: NVARCHAR(max)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_longtext\n                              type: NVARCHAR(MAX)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_text\n                              type: NVARCHAR(MAX)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_char\n                              type: CHAR(5)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_date\n                              type: DATE\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_datetime\n                              type: DATETIME\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_timestamp\n                              type: DATETIME\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_time\n                              type: TIME\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_bigint\n                              type: BIGINT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_tinyint\n                              type: TINYINT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_smallint\n                              type: SMALLINT\n                              remarks: small int comment\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_decimal\n                              type: DECIMAL(19, 5)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_double\n                              type: FLOAT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_bit\n                              type: BIT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_bool\n                              type: BIT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_json\n                              type: NVARCHAR(MAX)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_tinyblob\n                              type: VARBINARY(MAX)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_mediumblob\n                              type: VARBINARY(MAX)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_longblob\n                              type: VARBINARY(MAX)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_tinyint_8\n                              type: TINYINT\n                    remarks: my table comment\n                    tableName: all_type\n"
  },
  {
    "path": "src/test/resources/jdl/all_types-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: all_types-create_table_all\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          dbms: mysql,mariadb\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: my_id\n                              type: VARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              defaultValueNumeric: 55\n                              name: my_int\n                              type: INT\n                        - column:\n                              name: my_int_null\n                              type: INT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              defaultValue: default of varchar 50\n                              name: my_varchar_50\n                              type: VARCHAR(50)\n                        - column:\n                              name: my_varchar_50_null\n                              type: VARCHAR(50)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_varchar_512\n                              remarks: super varchar 512\n                              type: VARCHAR(512)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_tinytext\n                              type: TINYTEXT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_mediumtext\n                              type: MEDIUMTEXT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_longtext\n                              type: LONGTEXT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_text\n                              type: TEXT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_char\n                              type: CHAR(5)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_date\n                              type: date\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_datetime\n                              type: datetime\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_timestamp\n                              type: timestamp\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_time\n                              type: time\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_bigint\n                              type: BIGINT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_tinyint\n                              type: TINYINT(3)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_smallint\n                              remarks: small int comment\n                              type: SMALLINT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_decimal\n                              type: DECIMAL(19, 5)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_double\n                              type: DOUBLE\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_bit\n                              type: BIT(1)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_bool\n                              type: BIT(1)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_json\n                              type: JSON\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_tinyblob\n                              type: TINYBLOB\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_mediumblob\n                              type: MEDIUMBLOB\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_longblob\n                              type: LONGBLOB\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_tinyint_8\n                              type: TINYINT(3)\n                    remarks: my table comment\n                    tableName: all_type\n    - changeSet:\n          id: all_types-create_table_ansi_sql\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          dbms: mysql,mariadb\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_year\n                              type: YEAR(4)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_mediumint\n                              type: MEDIUMINT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_float\n                              type: FLOAT(12)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_enum_sql\n                              type: ENUM('value_one','value_two','value_three')\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_set\n                              type: SET('set_one','set_two','set_three')\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_geometry\n                              type: GEOMETRY\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_blob\n                              remarks: blob comment\n                              type: BLOB\n                    remarks: my table comment\n                    tableName: mysql_type\n    - changeSet:\n          id: all_types-create_table_postgres\n          author: jason.long\n          dbms: postgresql\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              name: my_boolean\n                              type: boolean\n                        - column:\n                              name: my_date\n                              type: date\n                        - column:\n                              name: my_time\n                              type: time\n                        - column:\n                              name: my_time_with_time_zone\n                              type: time with time zone\n                        - column:\n                              name: my_timestamp\n                              type: timestamp\n                        - column:\n                              name: my_timestamp_with_time_zone\n                              type: timestamp with time zone\n                        - column:\n                              name: my_real\n                              type: real\n                        - column:\n                              name: my_double_precision\n                              type: double precision\n                        - column:\n                              name: my_smallint\n                              type: smallint\n                        - column:\n                              name: my_integer\n                              type: integer\n                        - column:\n                              name: my_bigint\n                              type: bigint\n                        - column:\n                              name: my_money\n                              type: money\n                        - column:\n                              name: my_numeric\n                              type: numeric\n                        - column:\n                              name: my_bpchar\n                              type: bpchar\n                        - column:\n                              name: my_char\n                              type: char\n                        - column:\n                              name: my_text\n                              type: text\n                        - column:\n                              name: my_varchar\n                              type: varchar\n                        - column:\n                              name: my_bytea\n                              type: bytea\n                        - column:\n                              name: my_json\n                              type: json\n                        - column:\n                              name: my_uuid\n                              type: uuid\n                    tableName:  postgres_type\n    - changeSet:\n          id: all_types-create_table_oracle\n          author: mhmmdd\n          dbms: oracle\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: my_id\n                              type: VARCHAR(25)\n                        - column:\n                              name: my_boolean\n                              type: boolean\n                        - column:\n                              name: my_tinyint\n                              type: tinyint\n                        - column:\n                              name: my_int\n                              type: int\n                        - column:\n                              name: my_bigint\n                              type: bigint\n                        - column:\n                              name: my_float\n                              type: float\n                        - column:\n                              name: my_double\n                              type: double\n                        - column:\n                              name: my_decimal\n                              type: decimal\n                        - column:\n                              name: my_number\n                              type: number\n                        - column:\n                              name: my_blob\n                              remarks: blob comment\n                              type: blob\n                        - column:\n                              name: my_datetime\n                              type: datetime\n                        - column:\n                              name: my_time\n                              type: time\n                        - column:\n                              name: my_timestamp\n                              type: timestamp\n                        - column:\n                              name: my_date\n                              type: date\n                        - column:\n                              name: my_char\n                              type: char\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_varchar_50\n                              type: VARCHAR(50)\n                        - column:\n                              name: my_varchar_50_null\n                              type: VARCHAR(50)\n                        - column:\n                              name: my_nchar\n                              type: nchar\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: my_nvarchar_50\n                              type: NVARCHAR(50)\n                        - column:\n                              name: my_nvarchar_50_null\n                              type: NVARCHAR(50)\n                        - column:\n                              name: my_clob\n                              type: clob\n                        - column:\n                              name: my_currency\n                              type: currency\n                        - column:\n                              name: my_uuid\n                              type: uuid\n                    tableName: oracle_type\n                    remarks: my table comment\n"
  },
  {
    "path": "src/test/resources/jdl/display_field_many_to_one-expected-sqlserver.jdl",
    "content": "entity Player {\n    name String required unique maxlength(255)\n}\n\nentity Team {\n    abrev String required unique maxlength(4),\n    name String required unique maxlength(255)\n}\n\n// Relations\nrelationship ManyToOne {\n    Player{team(abrev) required} to Team{player(name)}\n}\n"
  },
  {
    "path": "src/test/resources/jdl/display_field_many_to_one-expected.jdl",
    "content": "entity Player {\n    /** Used as display field because it is the first unique not foreign key column */\n    name String required unique maxlength(255)\n}\n\nentity Team {\n    /** Used as display field because it is the first unique not foreign key column */\n    abrev String required unique maxlength(4),\n    name String required unique maxlength(255)\n}\n\n// Relations\nrelationship ManyToOne {\n    Player{team(abrev) required} to Team{player(name)}\n}\n"
  },
  {
    "path": "src/test/resources/jdl/display_field_many_to_one-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: create_table_team-1\n          author: jason.long\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  unique: true\n                              name: abrev\n                              type: varchar(4)\n                              remarks: Used as display field because it is the first unique not foreign key column\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  unique: true\n                              name: name\n                              type: varchar(255)\n                    tableName: team\n    - changeSet:\n          id: create_table_player-2\n          author: jason.long\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  unique: true\n                              name: name\n                              type: varchar(255)\n                              remarks: Used as display field because it is the first unique not foreign key column\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: team_id\n                              type: bigint\n                    tableName: player\n    - changeSet:\n          id: add_foreign_key_player_team-3\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - addForeignKeyConstraint:\n                    baseColumnNames: team_id\n                    baseTableName: player\n                    constraintName: fk_player_team\n                    deferrable: false\n                    initiallyDeferred: false\n                    referencedColumnNames: id\n                    referencedTableName: team\n                    validate: true\n"
  },
  {
    "path": "src/test/resources/jdl/duplicate_names-expected.jdl",
    "content": "entity Task {\n    name String required maxlength(255),\n    summary String maxlength(255),\n    description String maxlength(255),\n    priority String maxlength(255),\n    status String maxlength(255)\n}\n\nentity Worker {\n    name String required maxlength(255),\n    details String maxlength(255)\n}\n\n// Relations\nrelationship ManyToOne {\n    Task{assignee} to Worker{task}\n}\n\nrelationship ManyToOne {\n    Task{author} to Worker{taskOfAuthor}\n}\n\nrelationship ManyToOne {\n    Task{someOtherAuthor} to Worker{taskOfSomeOtherAuthor}\n}\n\nrelationship ManyToOne {\n    Task{evenMoreAuthor} to Worker{taskOfEvenMoreAuthor}\n}\n"
  },
  {
    "path": "src/test/resources/jdl/duplicate_names-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n- changeSet:\n    id: 1674449168689-1\n    author: Generated with liquibase:generate-changelog from maven\n    changes:\n    - createTable:\n        columns:\n        - column:\n            autoIncrement: true\n            constraints:\n              nullable: false\n              primaryKey: true\n              primaryKeyName: task_pkey\n            name: id\n            type: BIGINT\n        - column:\n            constraints:\n              nullable: false\n            name: name\n            type: VARCHAR(255)\n        - column:\n            name: summary\n            type: VARCHAR(255)\n        - column:\n            name: description\n            type: VARCHAR(255)\n        - column:\n            name: priority\n            type: VARCHAR(255)\n        - column:\n            name: assignee_id\n            type: BIGINT\n        - column:\n            name: author_id\n            type: BIGINT\n        - column:\n            name: some_other_author_id\n            type: BIGINT\n        - column:\n            name: even_more_author_id\n            type: BIGINT\n        - column:\n            name: status\n            type: VARCHAR(255)\n        tableName: task\n- changeSet:\n    id: 1674449168689-2\n    author: Generated with liquibase:generate-changelog from maven\n    changes:\n    - createTable:\n        columns:\n        - column:\n            autoIncrement: true\n            constraints:\n              nullable: false\n              primaryKey: true\n              primaryKeyName: worker_pkey\n            name: id\n            type: BIGINT\n        - column:\n            constraints:\n              nullable: false\n            name: name\n            type: VARCHAR(255)\n        - column:\n            name: details\n            type: VARCHAR(255)\n        tableName: worker\n- changeSet:\n    id: 1674449168689-3\n    author: Generated with liquibase:generate-changelog from maven\n    changes:\n    - addForeignKeyConstraint:\n        baseColumnNames: assignee_id\n        baseTableName: task\n        constraintName: task_assignee_id_fkey\n        deferrable: false\n        initiallyDeferred: false\n        onDelete: NO ACTION\n        onUpdate: NO ACTION\n        referencedColumnNames: id\n        referencedTableName: worker\n        validate: true\n- changeSet:\n    id: 1674449168689-4\n    author: Generated with liquibase:generate-changelog from maven\n    changes:\n    - addForeignKeyConstraint:\n        baseColumnNames: author_id\n        baseTableName: task\n        constraintName: task_author_id_fkey\n        deferrable: false\n        initiallyDeferred: false\n        onDelete: NO ACTION\n        onUpdate: NO ACTION\n        referencedColumnNames: id\n        referencedTableName: worker\n        validate: true\n- changeSet:\n    id: 1674449168689-5\n    author: Generated with liquibase:generate-changelog from maven\n    changes:\n    - addForeignKeyConstraint:\n        baseColumnNames: some_other_author_id\n        baseTableName: task\n        constraintName: task_some_other_author_id_fkey\n        deferrable: false\n        initiallyDeferred: false\n        onDelete: NO ACTION\n        onUpdate: NO ACTION\n        referencedColumnNames: id\n        referencedTableName: worker\n        validate: true\n- changeSet:\n    id: 1674449168689-6\n    author: Generated with liquibase:generate-changelog from maven\n    changes:\n    - addForeignKeyConstraint:\n        baseColumnNames: even_more_author_id\n        baseTableName: task\n        constraintName: task_even_more_author_id_fkey\n        deferrable: false\n        initiallyDeferred: false\n        onDelete: NO ACTION\n        onUpdate: NO ACTION\n        referencedColumnNames: id\n        referencedTableName: worker\n        validate: true\n\n"
  },
  {
    "path": "src/test/resources/jdl/enum-expected-sqlserver.jdl",
    "content": "entity City {\n    id String required maxlength(25),\n    name String maxlength(45),\n    /** city_status comment */\n    cityStatus CityStatus required,\n    cityType String maxlength(6)\n}\n\n/** city_status comment */\nenum CityStatus {\n}\n"
  },
  {
    "path": "src/test/resources/jdl/enum-expected.jdl",
    "content": "entity City {\n    id String required maxlength(25),\n    name String maxlength(45),\n    /** city_status comment */\n    cityStatus CityStatus required,\n    /** native enum comment */\n    cityType CityType\n}\n\n/** city_status comment */\nenum CityStatus {\n}\n"
  },
  {
    "path": "src/test/resources/jdl/enum-liquibase-changeset-sqlserver.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: enum-create-table-city\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: NVARCHAR(25)\n                        - column:\n                              name: name\n                              type: NVARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: city_status_id\n                              type: NVARCHAR(25)\n                              remarks: city_status comment\n                    tableName: city\n    - changeSet:\n          id: enum-add-field-sqlserver\n          author: jason.long (generated)\n#          dbms: sqlserver\n          changes:\n              - addColumn:\n                    tableName: city\n                    columns:\n                    - column:\n                          name: city_type\n                          remarks: native enum comment\n                          type: NVARCHAR(6)\n                          constraints:\n                              check: CITY_TYPE in ('small', 'big', 'mega')\n    - changeSet:\n          id: enum-create-table-city_status\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: NVARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  unique: true\n                              name: name\n                              type: NVARCHAR(255)\n                    remarks: city_status comment\n                    tableName: city_status\n    - changeSet:\n          id: enum-add-idx_city_city_status\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createIndex:\n                    columns:\n                        - column:\n                              name: city_status_id\n                    indexName: fk_city_city_status1_idx\n                    tableName: city\n    - changeSet:\n          id: enum-add-fk_city_city_status\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - addForeignKeyConstraint:\n                    baseColumnNames: city_status_id\n                    baseTableName: city\n                    constraintName: fk_city_city_status1\n                    deferrable: false\n                    initiallyDeferred: false\n                    onDelete: RESTRICT\n                    onUpdate: RESTRICT\n                    referencedColumnNames: id\n                    referencedTableName: city_status\n                    validate: true\n\n"
  },
  {
    "path": "src/test/resources/jdl/enum-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: enum-create-table-city\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: VARCHAR(25)\n                        - column:\n                              name: name\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: city_status_id\n                              type: VARCHAR(25)\n                    tableName: city\n    - changeSet:\n          id: enum-add-field-mysql\n          author: jason.long (generated)\n          dbms: mysql,mariadb\n          changes:\n              - addColumn:\n                    tableName: city\n                    columns:\n                    - column:\n                          name: city_type\n                          remarks: native enum comment\n                          type: ENUM('small', 'big', 'mega')\n    - changeSet:\n          id: enum-add-enum-type-postgres\n          author: jason.long\n          dbms: postgresql\n          changes:\n              - sql: create type city_type as enum ('small', 'big', 'mega');\n              - rollback: drop type city_type;\n    - changeSet:\n          id: enum-add-field-oracle\n          author: mhmmdd\n          dbms: oracle\n          changes:\n              # create enum constraint\n              # https://dba.stackexchange.com/a/81762\n              - sql: ALTER TABLE CITY\n                     ADD (CITY_TYPE VARCHAR2(6)\n                     CONSTRAINT city_type_value CHECK (CITY_TYPE in ('small', 'big', 'mega')));\n                     COMMENT ON COLUMN CITY.CITY_TYPE is 'native enum comment'\n              - rollback: ALTER TABLE CITY DROP COLUMN CITY_TYPE\n    - changeSet:\n          id: enum-add-field-postgres\n          author: jason.long\n          dbms: postgresql\n          changes:\n              - addColumn:\n                    tableName: city\n                    columns:\n                        - column:\n                              name: city_type\n                              remarks: native enum comment\n                              type: city_type\n    - changeSet:\n          id: enum-create-table-city_status\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: VARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  unique: true\n                              name: name\n                              type: VARCHAR(255)\n                    remarks: city_status comment\n                    tableName: city_status\n    - changeSet:\n          id: enum-add-idx_city_city_status\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createIndex:\n                    columns:\n                        - column:\n                              name: city_status_id\n                    indexName: fk_city_city_status1_idx\n                    tableName: city\n    - changeSet:\n          id: enum-add-fk_city_city_status\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - addForeignKeyConstraint:\n                    baseColumnNames: city_status_id\n                    baseTableName: city\n                    constraintName: fk_city_city_status1\n                    deferrable: false\n                    initiallyDeferred: false\n                    onDelete: RESTRICT\n                    onUpdate: RESTRICT\n                    referencedColumnNames: id\n                    referencedTableName: city_status\n                    validate: true\n"
  },
  {
    "path": "src/test/resources/jdl/many_to_one-expected.jdl",
    "content": "/** many_to_one_child comment */\nentity ManyToOneChild {\n    id String required maxlength(25),\n    name String required maxlength(45),\n    other String required maxlength(45)\n}\n\n/** many_to_one_main comment */\nentity ManyToOneMain {\n    id String required maxlength(25),\n    name String required maxlength(45),\n    other String required maxlength(45)\n}\n\n// Relations\n// many_to_one_main comment\nrelationship ManyToOne {\n    ManyToOneMain{manyToOneChild required} to ManyToOneChild{manyToOneMain}\n}\n"
  },
  {
    "path": "src/test/resources/jdl/many_to_one-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: many_to_one-1\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: VARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: name\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: other\n                              type: VARCHAR(45)\n                    remarks: many_to_one_child comment\n                    tableName: many_to_one_child\n    - changeSet:\n          id: many_to_one-2\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: VARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: name\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: other\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: many_to_one_child_id\n                              type: VARCHAR(25)\n                    remarks: many_to_one_main comment\n                    tableName: many_to_one_main\n    - changeSet:\n          id: many_to_one-3\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createIndex:\n                    columns:\n                        - column:\n                              name: many_to_one_child_id\n                    indexName: fk_many_to_one_main_many_to_one_child1_idx\n                    tableName: many_to_one_main\n    - changeSet:\n          id: many_to_one-4\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - addForeignKeyConstraint:\n                    baseColumnNames: many_to_one_child_id\n                    baseTableName: many_to_one_main\n                    constraintName: fk_many_to_one_main_many_to_one_child1\n                    deferrable: false\n                    initiallyDeferred: false\n                    onDelete: RESTRICT\n                    onUpdate: RESTRICT\n                    referencedColumnNames: id\n                    referencedTableName: many_to_one_child\n                    validate: true\n"
  },
  {
    "path": "src/test/resources/jdl/one_to_one-expected.jdl",
    "content": "entity OneToOneChild {\n    id String required maxlength(25),\n    name String required maxlength(45),\n    other String required maxlength(45)\n}\n\n/** one_to_one_main comment */\nentity OneToOneMain {\n    id String required maxlength(25),\n    name String required maxlength(45),\n    other String required maxlength(45)\n}\n\n// Relations\n// one_to_one_main comment\nrelationship OneToOne {\n    OneToOneMain{oneToOneChild required} to OneToOneChild{oneToOneMain}\n}\n"
  },
  {
    "path": "src/test/resources/jdl/one_to_one-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: one_to_one-1\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: VARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: name\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: other\n                              type: VARCHAR(45)\n                    tableName: one_to_one_child\n    - changeSet:\n          id: one_to_one-2\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: VARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: name\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: other\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  unique: true\n                              name: one_to_one_child_id\n                              type: VARCHAR(25)\n                    remarks: one_to_one_main comment\n                    tableName: one_to_one_main\n    - changeSet:\n          id: one_to_one-3\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - addForeignKeyConstraint:\n                    baseColumnNames: one_to_one_child_id\n                    baseTableName: one_to_one_main\n                    constraintName: fk_one_to_one_main_one_to_one_child1\n                    deferrable: false\n                    initiallyDeferred: false\n                    onDelete: RESTRICT\n                    onUpdate: RESTRICT\n                    referencedColumnNames: id\n                    referencedTableName: one_to_one_child\n                    validate: true\n"
  },
  {
    "path": "src/test/resources/jdl/one_to_one_main_map-expected.jdl",
    "content": "entity OneToOneChildMap {\n    name String required maxlength(45)\n}\n\n/** one_to_one_main_map comment */\nentity OneToOneMainMap {\n    id String required maxlength(25),\n    name String required maxlength(45),\n    other String required maxlength(45)\n}\n\n// Relations\nrelationship ManyToOne {\n    OneToOneChildMap{oneToOneMainMap required} to OneToOneMainMap{oneToOneChildMap}\n}\n"
  },
  {
    "path": "src/test/resources/jdl/one_to_one_main_map-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: one_to_one_main_map-1\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: one_to_one_main_map_id\n                              type: VARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: name\n                              type: VARCHAR(45)\n                    tableName: one_to_one_child_map\n    - changeSet:\n          id: one_to_one_main_map-2\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: VARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: name\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: other\n                              type: VARCHAR(45)\n                    remarks: one_to_one_main_map comment\n                    tableName: one_to_one_main_map\n    - changeSet:\n          id: one_to_one_main_map-3\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - addForeignKeyConstraint:\n                    baseColumnNames: one_to_one_main_map_id\n                    baseTableName: one_to_one_child_map\n                    constraintName: fk_one_to_one_child_map_one_to_one_main_map1\n                    deferrable: false\n                    initiallyDeferred: false\n                    onDelete: RESTRICT\n                    onUpdate: RESTRICT\n                    referencedColumnNames: id\n                    referencedTableName: one_to_one_main_map\n                    validate: true\n\n"
  },
  {
    "path": "src/test/resources/jdl/override_jdl_types-expected-postgresql.jdl",
    "content": "entity Override {\n    /** This column should be overridden to JDL type Float from the default of BigDecimal. */\n    f Float required\n}\n"
  },
  {
    "path": "src/test/resources/jdl/override_jdl_types-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: override_jdl_types-create_table\n          author: jason.long\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: f\n                              type: numeric\n                              remarks: This column should be overridden to JDL type Float from the default of BigDecimal.\n                    tableName: override\n"
  },
  {
    "path": "src/test/resources/jdl/parent_child-expected.jdl",
    "content": "entity Child {\n    id String required maxlength(25),\n    name String required maxlength(45),\n    other String required maxlength(45)\n}\n\nentity Parent {\n    id String required maxlength(25),\n    name String required maxlength(45),\n    other String required maxlength(45)\n}\n\n// Relations\n// TODO This is a pure ManyToMany relation (delete me and decide owner side)\n// parent_has_child comment\nrelationship ManyToMany {\n    ParentHasChild{parent required} to Parent{parentHasChild}\n}\n\n// TODO This is a pure ManyToMany relation (delete me and decide owner side)\n// parent_has_child comment\nrelationship ManyToMany {\n    ParentHasChild{child required} to Child{parentHasChild}\n}\n"
  },
  {
    "path": "src/test/resources/jdl/parent_child-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: parent_child-1\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: VARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: name\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: other\n                              type: VARCHAR(45)\n                    tableName: child\n    - changeSet:\n          id: parent_child-2\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: VARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: name\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: other\n                              type: VARCHAR(45)\n                    tableName: parent\n    - changeSet:\n          id: parent_child-3\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: parent_id\n                              type: VARCHAR(25)\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: child_id\n                              type: VARCHAR(25)\n                    remarks: parent_has_child comment\n                    tableName: parent_has_child\n    - changeSet:\n          id: parent_child-4\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createIndex:\n                    columns:\n                        - column:\n                              name: child_id\n                    indexName: fk_parent_has_child_child1_idx\n                    tableName: parent_has_child\n    - changeSet:\n          id: parent_child-5\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createIndex:\n                    columns:\n                        - column:\n                              name: parent_id\n                    indexName: fk_parent_has_child_parent1_idx\n                    tableName: parent_has_child\n    - changeSet:\n          id: parent_child-6\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - addForeignKeyConstraint:\n                    baseColumnNames: child_id\n                    baseTableName: parent_has_child\n                    constraintName: fk_parent_has_child_child1\n                    deferrable: false\n                    initiallyDeferred: false\n                    onDelete: RESTRICT\n                    onUpdate: RESTRICT\n                    referencedColumnNames: id\n                    referencedTableName: child\n                    validate: true\n    - changeSet:\n          id: parent_child-7\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - addForeignKeyConstraint:\n                    baseColumnNames: parent_id\n                    baseTableName: parent_has_child\n                    constraintName: fk_parent_has_child_parent1\n                    deferrable: false\n                    initiallyDeferred: false\n                    onDelete: RESTRICT\n                    onUpdate: RESTRICT\n                    referencedColumnNames: id\n                    referencedTableName: parent\n                    validate: true\n"
  },
  {
    "path": "src/test/resources/jdl/prefix-expected.jdl",
    "content": "/** many_to_one_child comment */\nentity ManyToOneChild {\n    name String required maxlength(45),\n    other String required maxlength(45)\n}\n\n/** many_to_one_main comment */\nentity ManyToOneMain {\n    name String required maxlength(45),\n    other String required maxlength(45)\n}\n\n// Relations\n// many_to_one_main comment\nrelationship ManyToOne {\n    ManyToOneMain{manyToOneChild required} to ManyToOneChild{manyToOneMain}\n}\n"
  },
  {
    "path": "src/test/resources/jdl/prefix-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: many_to_one_prefix-1\n          author: jason.long\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: name\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: other\n                              type: VARCHAR(45)\n                    remarks: many_to_one_child comment\n                    tableName: t_many_to_one_child\n    - changeSet:\n          id: many_to_one-2\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: name\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: other\n                              type: VARCHAR(45)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: many_to_one_child_id\n                              type: bigint\n                    remarks: many_to_one_main comment\n                    tableName: t_many_to_one_main\n    - changeSet:\n          id: many_to_one-3\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createIndex:\n                    columns:\n                        - column:\n                              name: many_to_one_child_id\n                    indexName: fk_many_to_one_main_many_to_one_child1_idx\n                    tableName: t_many_to_one_main\n    - changeSet:\n          id: many_to_one-4\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - addForeignKeyConstraint:\n                    baseColumnNames: many_to_one_child_id\n                    baseTableName: t_many_to_one_main\n                    constraintName: fk_many_to_one_main_many_to_one_child1\n                    deferrable: false\n                    initiallyDeferred: false\n                    onDelete: RESTRICT\n                    onUpdate: RESTRICT\n                    referencedColumnNames: id\n                    referencedTableName: t_many_to_one_child\n                    validate: true\n"
  },
  {
    "path": "src/test/resources/jdl/prune-expected.jdl",
    "content": "entity Demo {\n}\n"
  },
  {
    "path": "src/test/resources/jdl/prune-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: prune-1\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              autoIncrement: true\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: BIGINT\n                    tableName: class\n    - changeSet:\n          id: prune-2\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              autoIncrement: true\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: BIGINT\n                    tableName: demo\n    - changeSet:\n          id: prune-3\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              autoIncrement: true\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: BIGINT\n                    tableName: student_detail\n\n"
  },
  {
    "path": "src/test/resources/jdl/readonly-expected-sqlserver.jdl",
    "content": "/** view */\n@readOnly\nentity Nonupdatable {\n    id Long required,\n    num Integer required\n}\n\nentity TestTable {\n    num Integer required\n}\n\n/** view */\n@readOnly\nentity Updatable {\n    id Long required,\n    num Integer required\n}\n"
  },
  {
    "path": "src/test/resources/jdl/readonly-expected.jdl",
    "content": "/** view */\n@readOnly\nentity Nonupdatable {\n    id Long required,\n    num Integer required\n}\n\nentity TestTable {\n    num Integer required\n}\n\n/** view */\nentity Updatable {\n    id Long required,\n    num Integer required\n}\n"
  },
  {
    "path": "src/test/resources/jdl/readonly-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: view-create-table\n          author: jason.long\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: num\n                              type: int\n                    tableName: test_table\n    - changeSet:\n          id: view-create-view-updateable\n          author: jason.long\n          changes:\n              - createView:\n                    fullDefinition: false\n                    selectQuery: select t.* from test_table t\n                    viewName: updatable\n    - changeSet:\n          id: view-create-view-nonupdateable\n          author: jason.long\n          dbms: '!oracle'\n          changes:\n              - createView:\n                    fullDefinition: false\n                    selectQuery: select distinct t.* from test_table t\n                    viewName: nonupdatable\n    -   changeSet:\n            id: view-create-view-nonupdateable-oracle\n            author: jason.long\n            dbms: oracle\n            changes:\n                -   createView:\n                        fullDefinition: false\n                        selectQuery: select distinct t.* from test_table t with read only\n                        viewName: nonupdatable\n"
  },
  {
    "path": "src/test/resources/jdl/reflexive_relationship-expected.jdl",
    "content": "entity Invoice {\n    num String required unique maxlength(10),\n    amount BigDecimal required\n}\n\n// Relations\nrelationship OneToOne {\n    Invoice{parent(num)} to Invoice{invoice(num)}\n}\n"
  },
  {
    "path": "src/test/resources/jdl/reflexive_relationship-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: create_table_invoices-1\n          author: jason.long\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  unique: true\n                              name: num\n                              type: varchar(10)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: amount\n                              type: DECIMAL(19, 5)\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  unique: true\n                              name: parent_id\n                              type: bigint\n                    tableName: invoice\n    - changeSet:\n          id: add_reflexive_foreign_key-3\n          author: jason.long\n          changes:\n              - addForeignKeyConstraint:\n                    baseColumnNames: parent_id\n                    baseTableName: invoice\n                    constraintName: fk_invoice_parent\n                    referencedColumnNames: id\n                    referencedTableName: invoice\n                    validate: true\n"
  },
  {
    "path": "src/test/resources/jdl/table_name-expected.jdl",
    "content": "entity T(t) {\n    f Integer\n}\n"
  },
  {
    "path": "src/test/resources/jdl/table_name-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: table_name-1\n          author: jason.long\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              name: f\n                              type: int\n                    tableName: t\n"
  },
  {
    "path": "src/test/resources/jdl/tables-only-expected.jdl",
    "content": "entity TestTable {\n    num Integer required\n}\n"
  },
  {
    "path": "src/test/resources/jdl/tables-only-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: view-create-table\n          author: jason.long\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: num\n                              type: int\n                    tableName: test_table\n    - changeSet:\n          id: view-create-view-updateable\n          author: jason.long\n          changes:\n              - createView:\n                    fullDefinition: false\n                    selectQuery: select t.* from test_table t\n                    viewName: updatable\n    - changeSet:\n          id: view-create-view-nonupdateable\n          author: jason.long\n          changes:\n              - createView:\n                    fullDefinition: false\n                    selectQuery: select distinct t.* from test_table t\n                    viewName: nonupdatable\n"
  },
  {
    "path": "src/test/resources/jdl/undefined_error-expected.jdl",
    "content": "//Place hol"
  },
  {
    "path": "src/test/resources/jdl/undefined_error-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: undefined_unsupported-1\n          author: jason.long\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              name: supported\n                              type: integer\n                        - column:\n                              name: unsupported\n                              type: integer[]\n                    tableName: undefined_unsupported\n"
  },
  {
    "path": "src/test/resources/jdl/undefined_skip-expected.jdl",
    "content": "entity UndefinedUnsupported {\n    supported Integer\n}\n"
  },
  {
    "path": "src/test/resources/jdl/undefined_skip-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: undefined_unsupported-1\n          author: jason.long\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              name: supported\n                              type: integer\n                        - column:\n                              name: unsupported\n                              type: integer[]\n                    tableName: undefined_unsupported\n"
  },
  {
    "path": "src/test/resources/jdl/undefined_unsupported-expected.jdl",
    "content": "entity UndefinedUnsupported {\n    supported Integer,\n    /**  ARRAY */\n    unsupported Unsupported\n}\n"
  },
  {
    "path": "src/test/resources/jdl/undefined_unsupported-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: undefined_unsupported-1\n          author: jason.long\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: bigint\n                        - column:\n                              name: supported\n                              type: integer\n                        - column:\n                              name: unsupported\n                              type: integer[]\n                    tableName: undefined_unsupported\n"
  },
  {
    "path": "src/test/resources/jdl/unique-expected-oracle.jdl",
    "content": "entity Student {\n    id Integer required,\n    ssnnumber String required unique maxlength(100)\n}\n"
  },
  {
    "path": "src/test/resources/jdl/unique-expected-sqlserver.jdl",
    "content": "entity Student {\n    id Integer required,\n    ssnNumber String required unique maxlength(100)\n}\n"
  },
  {
    "path": "src/test/resources/jdl/unique-expected.jdl",
    "content": "entity Student {\n    id Integer required,\n    ssnNumber String required unique maxlength(100)\n}\n"
  },
  {
    "path": "src/test/resources/jdl/unique-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n- changeSet:\n    id: unique-1\n    author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n    changes:\n    - createTable:\n        columns:\n        - column:\n            autoIncrement: true\n            constraints:\n              nullable: false\n              primaryKey: true\n            name: id\n            type: INT\n        - column:\n            constraints:\n              nullable: false\n              unique: true\n            name: ssnNumber\n            type: VARCHAR(100)\n        tableName: student\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-expected-mariadb.jdl",
    "content": "entity UuidIdRequired {\n    id String required maxlength(36)\n}\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-expected-mysql.jdl",
    "content": "entity UuidIdRequired {\n    id String required maxlength(36)\n}\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-expected-postgresql.jdl",
    "content": "entity UuidIdRequired {\n    id UUID\n}\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-expected-sqlserver.jdl",
    "content": "entity UuidIdRequired {\n    id UUID\n}\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-expected.jdl",
    "content": "entity UuidIdRequired {\n    id UUID\n}\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-liquibase-changeset-sqlserver.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: uuid_id_required\n          author: jason.long\n          #dbms: sqlserver\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: uniqueidentifier\n                    tableName: uuid_id_required\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: uuid_id_required\n          author: jason.long\n          #dbms: mysql,mariadb\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: id\n                              type: uuid\n                    tableName: uuid_id_required\n"
  },
  {
    "path": "src/test/resources/jdl/views-expected.jdl",
    "content": "entity OrderDetails {\n    orderNumber String required maxlength(255),\n    productCode String required maxlength(50),\n    quantityOrdered Integer required,\n    priceEach BigDecimal required\n}\n\n/** view */\n@readOnly\nentity SalePerOrder {\n    orderNumber String required maxlength(255),\n    total BigDecimal\n}\n"
  },
  {
    "path": "src/test/resources/jdl/views-liquibase-changeset.yaml",
    "content": "databaseChangeLog:\n    - changeSet:\n          id: view-create-table\n          author: Generated with liquibase:generate-changelog from flyway sql from existing tests\n          changes:\n              - createTable:\n                    columns:\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: order_number\n                              type: VARCHAR(255)\n                        - column:\n                              constraints:\n                                  nullable: false\n                                  primaryKey: true\n                              name: product_code\n                              type: VARCHAR(50)\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: quantity_ordered\n                              type: INT\n                        - column:\n                              constraints:\n                                  nullable: false\n                              name: price_each\n                              type: DECIMAL(19, 5)\n                    tableName: order_details\n    - changeSet:\n          id: view-create-view-all\n          author: jason.long (generated)\n          dbms: '!oracle'\n          changes:\n              - createView:\n                    fullDefinition: false\n                    selectQuery: select order_details.order_number AS order_number,\n                                        sum((order_details.quantity_ordered * order_details.price_each)) AS total\n                                 from order_details\n                                 group by order_details.order_number\n                    viewName: sale_per_order\n    -   changeSet:\n            id: view-create-view-oracle\n            author: mhmmdd\n            dbms: oracle\n            changes:\n                -   createView:\n                        fullDefinition: false\n                        selectQuery: select order_details.order_number AS order_number,\n                                            cast(sum((order_details.quantity_ordered * order_details.price_each)) as number(19,5)) as total\n                                 from order_details\n                                 group by order_details.order_number with read only\n                        viewName: sale_per_order\n"
  },
  {
    "path": "src/test/resources/liquibase.properties",
    "content": "#liquibase.properties\nliquibase.sql.logLevel=DEBUG\nliquibase-logLevel=DEBUG\nurl=jdbc:mysql://localhost:3309/sql-to-jdl\nusername=root\npassword=\ndriver=com.mysql.jdbc.Driver\noutputChangeLogFile=src/test/resources/liquibase-outputChangeLog.yaml\n"
  }
]