Full Code of Blackdread/sql-to-jdl for AI

master fe33c6dd1bd3 cached
203 files
316.5 KB
74.3k tokens
492 symbols
1 requests
Download .txt
Showing preview only (373K chars total). Download the full file or copy to clipboard to get everything.
Repository: Blackdread/sql-to-jdl
Branch: master
Commit: fe33c6dd1bd3
Files: 203
Total size: 316.5 KB

Directory structure:
gitextract_dpof0rjx/

├── .editorconfig
├── .gitattributes
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       └── maven.yml
├── .gitignore
├── .mvn/
│   └── wrapper/
│       ├── maven-wrapper.jar
│       └── maven-wrapper.properties
├── .prettierignore
├── .prettierrc
├── .travis.yml
├── LICENSE
├── README.md
├── checkstyle-suppressions.xml
├── checkstyle.xml
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src/
    ├── main/
    │   ├── java/
    │   │   └── org/
    │   │       └── blackdread/
    │   │           └── sqltojava/
    │   │               ├── SqlToJavaApplication.java
    │   │               ├── config/
    │   │               │   ├── ApplicationProperties.java
    │   │               │   ├── CacheConfiguration.java
    │   │               │   ├── DatabaseObjectTypesConfigEnum.java
    │   │               │   ├── ExportFileStructureType.java
    │   │               │   └── UndefinedJdlTypeHandlingEnum.java
    │   │               ├── entity/
    │   │               │   ├── JdlEntity.java
    │   │               │   ├── JdlField.java
    │   │               │   ├── JdlFieldEnum.java
    │   │               │   ├── JdlRelation.java
    │   │               │   ├── JdlRelationGroup.java
    │   │               │   ├── RelationType.java
    │   │               │   ├── SqlColumn.java
    │   │               │   ├── SqlForeignKey.java
    │   │               │   ├── SqlTable.java
    │   │               │   └── impl/
    │   │               │       ├── JdlEntityImpl.java
    │   │               │       ├── JdlFieldImpl.java
    │   │               │       ├── JdlRelationGroupImpl.java
    │   │               │       ├── JdlRelationImpl.java
    │   │               │       ├── SqlColumnImpl.java
    │   │               │       └── SqlTableImpl.java
    │   │               ├── exporter/
    │   │               │   └── ExportFileStructureConfig.java
    │   │               ├── listener/
    │   │               │   └── SetDatabaseProfileApplicationEventListener.java
    │   │               ├── parser/
    │   │               │   └── SqlParser.java
    │   │               ├── pojo/
    │   │               │   ├── ColumnInformation.java
    │   │               │   ├── TableInformation.java
    │   │               │   ├── TableRelationInformation.java
    │   │               │   └── rowmaper/
    │   │               │       ├── ColumnInformationRowMapper.java
    │   │               │       ├── SqlServerColumnInformationRowMapper.java
    │   │               │       ├── SqlServerTableInformationRowMapper.java
    │   │               │       ├── TableInformationRowMapper.java
    │   │               │       └── TableRelationInformationRowMapper.java
    │   │               ├── repository/
    │   │               │   ├── InformationSchemaRepository.java
    │   │               │   ├── MsSqlPureSqlInformationSchemaRepository.java
    │   │               │   └── PureSqlInformationSchemaRepository.java
    │   │               ├── service/
    │   │               │   ├── InformationSchemaService.java
    │   │               │   ├── MsSqlJdlTypeService.java
    │   │               │   ├── MySqlJdlTypeService.java
    │   │               │   ├── OracleJdlTypeService.java
    │   │               │   ├── PostgresJdlTypeService.java
    │   │               │   ├── SqlJdlTypeService.java
    │   │               │   └── logic/
    │   │               │       ├── ExportService.java
    │   │               │       ├── JdlService.java
    │   │               │       ├── MustacheService.java
    │   │               │       └── SqlService.java
    │   │               ├── util/
    │   │               │   ├── AppUtil.java
    │   │               │   ├── JdbcUtil.java
    │   │               │   ├── JdlUtils.java
    │   │               │   ├── NamingConventionUtil.java
    │   │               │   ├── ResourceUtil.java
    │   │               │   └── SqlUtils.java
    │   │               └── view/
    │   │                   ├── JdlCommentView.java
    │   │                   ├── JdlEntityView.java
    │   │                   ├── JdlFieldView.java
    │   │                   ├── JdlRelationGroupView.java
    │   │                   ├── JdlRelationView.java
    │   │                   ├── impl/
    │   │                   │   ├── JdlEntityViewImpl.java
    │   │                   │   ├── JdlFieldViewImpl.java
    │   │                   │   ├── JdlRelationGroupViewImpl.java
    │   │                   │   └── JdlRelationViewImpl.java
    │   │                   └── mapper/
    │   │                       ├── JdlViewMapper.java
    │   │                       └── OptionalUtils.java
    │   └── resources/
    │       ├── application.yml
    │       ├── mustache/
    │       │   ├── application-entities-relations-views.mustache
    │       │   ├── application-grouped-relations-separate-views.mustache
    │       │   ├── application.mustache
    │       │   ├── entities.mustache
    │       │   ├── groupedmanytoonerelations.mustache
    │       │   ├── groupedonetoonerelations.mustache
    │       │   ├── manytomanyrelations.mustache
    │       │   ├── manytoonerelations.mustache
    │       │   ├── onetoonerelations.mustache
    │       │   ├── options.mustache
    │       │   ├── relations.mustache
    │       │   ├── views.mustache
    │       │   └── viewsrelations.mustache
    │       ├── reserved/
    │       │   └── keywords.json
    │       └── sql/
    │           ├── mysql_mariadb-getAllTableInformation.sql
    │           ├── mysql_mariadb-getAllTableRelationInformation.sql
    │           ├── mysql_mariadb-getFullColumnInformationOfTable.sql
    │           ├── oracle-getAllTableInformation.sql
    │           ├── oracle-getAllTableRelationInformation.sql
    │           ├── oracle-getFullColumnInformationOfTable.sql
    │           ├── postgresql-getAllTableInformation.sql
    │           ├── postgresql-getAllTableRelationInformation.sql
    │           ├── postgresql-getFullColumnInformationOfTable.sql
    │           ├── sqlserver-getAllTableInformation.sql
    │           ├── sqlserver-getAllTableRelationInformation.sql
    │           └── sqlserver-getFullColumnInformationOfTable.sql
    └── test/
        ├── java/
        │   └── org/
        │       └── blackdread/
        │           └── sqltojava/
        │               ├── AssertUtil.java
        │               ├── FileUtil.java
        │               ├── shared/
        │               │   ├── LoggingExtension.java
        │               │   ├── MainApplicationContextLoader.java
        │               │   ├── interfaces/
        │               │   │   ├── CompareJdlResultsTest.java
        │               │   │   ├── ContainersStartedTest.java
        │               │   │   ├── EnvironmentTest.java
        │               │   │   ├── JdbcContainerTest.java
        │               │   │   ├── LoggingTest.java
        │               │   │   └── ProfileActiveTest.java
        │               │   └── tests/
        │               │       ├── BaseJdbcContainerTest.java
        │               │       ├── SqlToJdlTransactionPerTestTest.java
        │               │       └── TransactionPerTestTest.java
        │               └── test/
        │                   ├── db/
        │                   │   ├── mssql/
        │                   │   │   └── MssqlSql2019Test.java
        │                   │   ├── mysql/
        │                   │   │   ├── MariaDBLatestTest.java
        │                   │   │   ├── Mysql57Test.java
        │                   │   │   ├── Mysql8Test.java
        │                   │   │   ├── Mysql9Test.java
        │                   │   │   └── MysqlLatestTest.java
        │                   │   ├── oracle/
        │                   │   │   └── OracleLatestTest.java
        │                   │   └── postgres/
        │                   │       ├── Postgres09Test.java
        │                   │       ├── Postgres10Test.java
        │                   │       ├── Postgres15Test.java
        │                   │       ├── Postgres17Test.java
        │                   │       ├── PostgresAddTableNameJdlTest.java
        │                   │       ├── PostgresDatabaseObjectPrefixTest.java
        │                   │       ├── PostgresLatestTest.java
        │                   │       └── PostgresOverrideJdlTypeTest.java
        │                   └── general/
        │                       ├── DatabaseObjectPrefixTest.java
        │                       ├── MustacheTest.java
        │                       ├── unsupported/
        │                       │   ├── PostgresUndefinedErrorTest.java
        │                       │   ├── PostgresUndefinedSkioTest.java
        │                       │   └── PostgresUndefinedUnsupportedTest.java
        │                       └── views/
        │                           └── PostgresDatabaseObjectTypesTest.java
        └── resources/
            ├── application.yml
            ├── container-license-acceptance.txt
            ├── db/
            │   └── changelog/
            │       └── db.changelog-master.yaml
            ├── jdl/
            │   ├── all_jdl_types-expected.jdl
            │   ├── all_types-expected-mariadb.jdl
            │   ├── all_types-expected-mysql.jdl
            │   ├── all_types-expected-oracle.jdl
            │   ├── all_types-expected-postgresql.jdl
            │   ├── all_types-expected-sqlserver.jdl
            │   ├── all_types-liquibase-changeset-sqlserver.yaml
            │   ├── all_types-liquibase-changeset.yaml
            │   ├── display_field_many_to_one-expected-sqlserver.jdl
            │   ├── display_field_many_to_one-expected.jdl
            │   ├── display_field_many_to_one-liquibase-changeset.yaml
            │   ├── duplicate_names-expected.jdl
            │   ├── duplicate_names-liquibase-changeset.yaml
            │   ├── enum-expected-sqlserver.jdl
            │   ├── enum-expected.jdl
            │   ├── enum-liquibase-changeset-sqlserver.yaml
            │   ├── enum-liquibase-changeset.yaml
            │   ├── many_to_one-expected.jdl
            │   ├── many_to_one-liquibase-changeset.yaml
            │   ├── one_to_one-expected.jdl
            │   ├── one_to_one-liquibase-changeset.yaml
            │   ├── one_to_one_main_map-expected.jdl
            │   ├── one_to_one_main_map-liquibase-changeset.yaml
            │   ├── override_jdl_types-expected-postgresql.jdl
            │   ├── override_jdl_types-liquibase-changeset.yaml
            │   ├── parent_child-expected.jdl
            │   ├── parent_child-liquibase-changeset.yaml
            │   ├── prefix-expected.jdl
            │   ├── prefix-liquibase-changeset.yaml
            │   ├── prune-expected.jdl
            │   ├── prune-liquibase-changeset.yaml
            │   ├── readonly-expected-sqlserver.jdl
            │   ├── readonly-expected.jdl
            │   ├── readonly-liquibase-changeset.yaml
            │   ├── reflexive_relationship-expected.jdl
            │   ├── reflexive_relationship-liquibase-changeset.yaml
            │   ├── table_name-expected.jdl
            │   ├── table_name-liquibase-changeset.yaml
            │   ├── tables-only-expected.jdl
            │   ├── tables-only-liquibase-changeset.yaml
            │   ├── undefined_error-expected.jdl
            │   ├── undefined_error-liquibase-changeset.yaml
            │   ├── undefined_skip-expected.jdl
            │   ├── undefined_skip-liquibase-changeset.yaml
            │   ├── undefined_unsupported-expected.jdl
            │   ├── undefined_unsupported-liquibase-changeset.yaml
            │   ├── unique-expected-oracle.jdl
            │   ├── unique-expected-sqlserver.jdl
            │   ├── unique-expected.jdl
            │   ├── unique-liquibase-changeset.yaml
            │   ├── uuid_id_required-expected-mariadb.jdl
            │   ├── uuid_id_required-expected-mysql.jdl
            │   ├── uuid_id_required-expected-postgresql.jdl
            │   ├── uuid_id_required-expected-sqlserver.jdl
            │   ├── uuid_id_required-expected.jdl
            │   ├── uuid_id_required-liquibase-changeset-sqlserver.yaml
            │   ├── uuid_id_required-liquibase-changeset.yaml
            │   ├── views-expected.jdl
            │   └── views-liquibase-changeset.yaml
            └── liquibase.properties

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org

root = true

[*]

# Change these settings to your own preference
indent_style = space
indent_size = 4

# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false

[{package,bower}.json]
indent_style = space
indent_size = 2


================================================
FILE: .gitattributes
================================================
# All text files should have the "lf" (Unix) line endings
* text eol=lf

# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.java text
*.js text
*.css text
*.html text

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.jar binary
*.pdf binary
*.eot binary
*.ttf binary
*.gzip binary
*.gz binary
*.ai binary
*.eps binary
*.swf binary
*.mwb binary

================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: maven
  directory: "/"
  schedule:
    interval: monthly
  open-pull-requests-limit: 15
  groups:
    maven-dependencies:
      update-types:
        - "patch"
        - "minor"
        - "major"


================================================
FILE: .github/workflows/maven.yml
================================================
name: Java CI

on: [push]

jobs:
    build:
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v3
            - name: Set up JDK 17
              uses: actions/setup-java@v3
              with:
                  distribution: 'adopt'
                  java-version: '17'
                  cache: 'maven'
            - name: Build and Run Tests
              run: mvn test --file pom.xml --batch-mode --update-snapshots --fail-at-end
            - name: Publish Test Report
              if: ${{ always() }}
              uses: scacap/action-surefire-report@v1


================================================
FILE: .gitignore
================================================
######################
# Project Specific
######################
classes/artifacts
/my-project-jdl.jh
/*.jdl
/*.jh

######################
# Eclipse
######################
*.pydevproject
.project
.metadata
tmp/
tmp/**/*
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
.factorypath
/src/main/resources/rebel.xml

# External tool builders
.externalToolBuilders/**

# Locally stored "Eclipse launch configurations"
*.launch

# CDT-specific
.cproject

# PDT-specific
.buildpath

######################
# Intellij
######################
.idea/
*.iml
*.iws
*.ipr
*.ids
*.orig

######################
# Visual Studio Code
######################
.vscode/

######################
# Maven
######################
log/
target/

######################
# Package Files
######################
*.jar
*.war
*.ear
*.db

######################
# Windows
######################
# Windows image file caches
Thumbs.db

# Folder config file
Desktop.ini

######################
# Mac OSX
######################
.DS_Store
.svn

# Thumbnails
._*

# Files that might appear on external disk
.Spotlight-V100
.Trashes

######################
# Directories
######################
#/build/
#/bin/
#/deploy/

######################
# Logs
######################
*.log

######################
# Others
######################
*.class
*.*~
*~
.merge_file*

######################
# Maven Wrapper
######################
!.mvn/wrapper/maven-wrapper.jar

######################
# ESLint
######################
.eslintcache


================================================
FILE: .mvn/wrapper/maven-wrapper.properties
================================================
distributionUrl=https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.zip


================================================
FILE: .prettierignore
================================================


================================================
FILE: .prettierrc
================================================
# Prettier configuration

printWidth: 140
singleQuote: true
tabWidth: 2
useTabs: false

# java rules:
overrides:
  - files: "*.java"
    options:
      tabWidth: 4


================================================
FILE: .travis.yml
================================================
language: java

#jdk:
#  - oraclejdk8

cache:
    directories:
        - $HOME/.m2

services:
  - mysql

before_install:
  - chmod +x mvnw

after_success:
  - mvn clean test
#  - mvn clean test jacoco:report
#  - mvn clean test jacoco:report coveralls:report


#notifications:
#  email:
#    - yoann.caplain@blackdread.org


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2018 Yoann CAPLAIN

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
[![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)
[![StackShare](https://img.shields.io/badge/tech-stack-0690fa.svg?style=flat)](https://stackshare.io/Blackdread/sql-to-jdl)

# sql-to-jdl
Tool to translate SQL databases to JDL format of jHipster (Created due to existing databases to be generated with jHipster and build angular-java web)

# Usage

```bash
#Download
git clone https://github.com/Blackdread/sql-to-jdl.git

# Modify configuration file application.yml at https://github.com/Blackdread/sql-to-jdl/blob/master/src/main/resources/application.yml

#Build, skip the tests for lack of time
mvn clean package -DskipTests

#Run
java -jar target/sql-to-java-*-SNAPSHOT.jar
```

Direct link to [application.yml](https://github.com/Blackdread/sql-to-jdl/blob/master/src/main/resources/application.yml)

_Don't forget to install git, maven 3 and java 17 before launching_

# Compatibility
This implementation works with 
  - mysql 5.7.x, 8.x, 9.x
  - mariadb 10.x
  - postgresql 9.x+
  - oracle 21
  - MsSQL 2019

Help 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.

# Testing
Setting up tests for new databases types or versions is easy.  Have a look existing tests.  
MsSQL and Oracle have tests created that are disabled because their implementations are incomplete.

Tests 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.

Each test needs the following files
  - {{test.name}}-liquibase-changeset.yaml
  - {{test.name}}-expected.jdl
  
To override the default name the files as
  - {{test.name}}-liquibase-changeset-{{db.typ}}.yaml
  - {{test.name}}-expected-{{db.type}}.jdl

If you need to change the tests run for a specific database type or version, use method hiding by implementing 

private static Stream<String> provideTestNames() in the subclass of SqlToJdlTransactionPerTestTest

In 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.

Currently the full test suite runs 11 test per database version which total nearly 80 tests.  
 
# Why not use tools like UML provided on jHipster?
- JDL from web is ok for a few entities but not for more than 100 entities and relations
- UML software and xml exporters could have worked (other tools on jHipster) but:
  - already many databases in production to be exported in JDL (faster to generate the JDL from it)
  - already working UML design with MySQL Workbench

# How to use
Just 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.

Set properties file:
- Schema name to export
- Tables names to be ignored
- Path of export file
- Database object prefixes to remove from entity name
- Include table name is JDL
- Undefined JDL type handling to ERROR, SKIP, or UNSUPPORTED
- Add JDL type overrides if necessary.

# After JDL file is generated
Still have some manual steps to do:
- review relations:
  - ManyToMany
  - Owner side display field
  - Inverse side field name and display field
  - Bidirectional or not
- add values to enums
- review validations of entities

# Default specific rules
Table is treated as enum if only 2 columns and both are: "id" AND ("code" OR "name")

Table is treated as ManyToMany if only 2 columns and both are foreign keys

# Links
[jHipster JDL](https://www.jhipster.tech/jdl/intro)

# An alternative for REST filter and sort
Different criterias, support for JPA and jOOQ dynamic filtering and sorting.

https://github.com/Blackdread/rest-filter


================================================
FILE: checkstyle-suppressions.xml
================================================
<?xml version="1.0"?>

<!DOCTYPE suppressions PUBLIC
    "-//Checkstyle//DTD SuppressionFilter Configuration 1.0//EN"
    "https://checkstyle.org/dtds/suppressions_1_0.dtd">

<suppressions>
    <suppress checks=".*"
              files=".[/\\]src[/\\]main[/\\]java[/\\]org[/\\]blackdread[/\\]sqltojava[/\\]jooq[/\\]generated[/\\]"/>
</suppressions>


================================================
FILE: checkstyle.xml
================================================
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
    "https://checkstyle.org/dtds/configuration_1_3.dtd">

<module name = "Checker">
    <property name="charset" value="UTF-8"/>

    <property name="severity" value="error"/>

    <property name="fileExtensions" value="java, properties, xml"/>
    <module name="BeforeExecutionExclusionFileFilter">
        <property name="fileNamePattern" value="module\-info\.java$"/>
    </module>

    <module name="TreeWalker">
        <module name="OuterTypeFilename"/>
        <module name="NoLineWrap">
            <property name="tokens" value="PACKAGE_DEF, IMPORT, STATIC_IMPORT"/>
        </module>
        <module name="LeftCurly" />
        <module name="RightCurly" />
        <module name="WhitespaceAfter"/>
        <module name="WhitespaceAround">
            <property name="allowEmptyConstructors" value="true"/>
            <property name="allowEmptyLambdas" value="true"/>
            <property name="allowEmptyMethods" value="true"/>
            <property name="allowEmptyTypes" value="true"/>
            <property name="allowEmptyLoops" value="true"/>
            <property name="allowEmptyCatches" value="true"/>
            <property name="ignoreEnhancedForColon" value="false"/>
            <property name="tokens"
                      value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR,
                    BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAMBDA, LAND,
                    LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY,
                    LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SWITCH, LITERAL_SYNCHRONIZED,
                    LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN,
                    NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR,
                    SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
            <message key="ws.notFollowed"
                     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)"/>
            <message key="ws.notPreceded"
                     value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
        </module>
        <module name="GenericWhitespace">
            <message key="ws.followed"
                     value="GenericWhitespace ''{0}'' is followed by whitespace."/>
            <message key="ws.preceded"
                     value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
            <message key="ws.illegalFollow"
                     value="GenericWhitespace ''{0}'' should followed by whitespace."/>
            <message key="ws.notPreceded"
                     value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
        </module>
        <module name="OneStatementPerLine"/>
        <module name="ModifierOrder"/>
        <module name="EmptyLineSeparator">
            <property name="tokens"
                      value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
                    STATIC_INIT, INSTANCE_INIT, CTOR_DEF, VARIABLE_DEF, RECORD_DEF,
                    COMPACT_CTOR_DEF"/>
            <property name="allowNoEmptyLineBetweenFields" value="true"/>
        </module>
        <module name="SeparatorWrap">
            <property name="id" value="SeparatorWrapDot"/>
            <property name="tokens" value="DOT"/>
            <property name="option" value="nl"/>
        </module>
        <module name="SeparatorWrap">
            <property name="id" value="SeparatorWrapComma"/>
            <property name="tokens" value="COMMA"/>
            <property name="option" value="EOL"/>
        </module>

        <module name="CustomImportOrder">
            <property name="sortImportsInGroupAlphabetically" value="true"/>
            <property name="separateLineBetweenGroups" value="true"/>
            <property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/>
            <property name="tokens" value="IMPORT, STATIC_IMPORT, PACKAGE_DEF"/>
        </module>
        <module name="MethodParamPad">
            <property name="tokens"
                      value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF,
                    SUPER_CTOR_CALL, ENUM_CONSTANT_DEF, RECORD_DEF"/>
        </module>
        <module name="NoWhitespaceBefore">
            <property name="tokens"
                      value="COMMA, SEMI, POST_INC, POST_DEC, DOT,
                    LABELED_STAT, METHOD_REF"/>
            <property name="allowLineBreaks" value="true"/>
        </module>
        <module name="ParenPad"/>
        <module name="AnnotationLocation">
            <property name="allowSamelineMultipleAnnotations" value="false"/>
            <property name="allowSamelineSingleParameterlessAnnotation" value="false"/>
            <property name="allowSamelineParameterizedAnnotation" value="false"/>
        </module>
    </module>
</module>


================================================
FILE: mvnw
================================================
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------

# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
#   JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
#   M2_HOME - location of maven2's installed home dir
#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
#     e.g. to debug Maven itself, use
#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------

if [ -z "$MAVEN_SKIP_RC" ] ; then

  if [ -f /etc/mavenrc ] ; then
    . /etc/mavenrc
  fi

  if [ -f "$HOME/.mavenrc" ] ; then
    . "$HOME/.mavenrc"
  fi

fi

# OS specific support.  $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
  CYGWIN*) cygwin=true ;;
  MINGW*) mingw=true;;
  Darwin*) darwin=true
    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
    if [ -z "$JAVA_HOME" ]; then
      if [ -x "/usr/libexec/java_home" ]; then
        export JAVA_HOME="`/usr/libexec/java_home`"
      else
        export JAVA_HOME="/Library/Java/Home"
      fi
    fi
    ;;
esac

if [ -z "$JAVA_HOME" ] ; then
  if [ -r /etc/gentoo-release ] ; then
    JAVA_HOME=`java-config --jre-home`
  fi
fi

if [ -z "$M2_HOME" ] ; then
  ## resolve links - $0 may be a link to maven's home
  PRG="$0"

  # need this for relative symlinks
  while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
      PRG="$link"
    else
      PRG="`dirname "$PRG"`/$link"
    fi
  done

  saveddir=`pwd`

  M2_HOME=`dirname "$PRG"`/..

  # make it fully qualified
  M2_HOME=`cd "$M2_HOME" && pwd`

  cd "$saveddir"
  # echo Using m2 at $M2_HOME
fi

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
  [ -n "$M2_HOME" ] &&
    M2_HOME=`cygpath --unix "$M2_HOME"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
  [ -n "$CLASSPATH" ] &&
    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi

# For Migwn, ensure paths are in UNIX format before anything is touched
if $mingw ; then
  [ -n "$M2_HOME" ] &&
    M2_HOME="`(cd "$M2_HOME"; pwd)`"
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
  # TODO classpath?
fi

if [ -z "$JAVA_HOME" ]; then
  javaExecutable="`which javac`"
  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
    # readlink(1) is not available as standard on Solaris 10.
    readLink=`which readlink`
    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
      if $darwin ; then
        javaHome="`dirname \"$javaExecutable\"`"
        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
      else
        javaExecutable="`readlink -f \"$javaExecutable\"`"
      fi
      javaHome="`dirname \"$javaExecutable\"`"
      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
      JAVA_HOME="$javaHome"
      export JAVA_HOME
    fi
  fi
fi

if [ -z "$JAVACMD" ] ; then
  if [ -n "$JAVA_HOME"  ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
      # IBM's JDK on AIX uses strange locations for the executables
      JAVACMD="$JAVA_HOME/jre/sh/java"
    else
      JAVACMD="$JAVA_HOME/bin/java"
    fi
  else
    JAVACMD="`which java`"
  fi
fi

if [ ! -x "$JAVACMD" ] ; then
  echo "Error: JAVA_HOME is not defined correctly." >&2
  echo "  We cannot execute $JAVACMD" >&2
  exit 1
fi

if [ -z "$JAVA_HOME" ] ; then
  echo "Warning: JAVA_HOME environment variable is not set."
fi

CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher

# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {

  if [ -z "$1" ]
  then
    echo "Path not specified to find_maven_basedir"
    return 1
  fi

  basedir="$1"
  wdir="$1"
  while [ "$wdir" != '/' ] ; do
    if [ -d "$wdir"/.mvn ] ; then
      basedir=$wdir
      break
    fi
    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
    if [ -d "${wdir}" ]; then
      wdir=`cd "$wdir/.."; pwd`
    fi
    # end of workaround
  done
  echo "${basedir}"
}

# concatenates all lines of a file
concat_lines() {
  if [ -f "$1" ]; then
    echo "$(tr -s '\n' ' ' < "$1")"
  fi
}

BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
  exit 1;
fi

export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
echo $MAVEN_PROJECTBASEDIR
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
  [ -n "$M2_HOME" ] &&
    M2_HOME=`cygpath --path --windows "$M2_HOME"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
  [ -n "$CLASSPATH" ] &&
    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi

WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain

exec "$JAVACMD" \
  $MAVEN_OPTS \
  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"


================================================
FILE: mvnw.cmd
================================================
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements.  See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership.  The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License.  You may obtain a copy of the License at
@REM
@REM    http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied.  See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------

@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM     e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------

@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%

@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")

@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre

@setlocal

set ERROR_CODE=0

@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal

@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome

echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error

:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init

echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error

@REM ==== END VALIDATION ====

:init

@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.

set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir

set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir

:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir

:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"

:endDetectBaseDir

IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig

@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%

:endReadAdditionalConfig

SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"

set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain

%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end

:error
set ERROR_CODE=1

:end
@endlocal & set ERROR_CODE=%ERROR_CODE%

if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost

@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause

if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%

exit /B %ERROR_CODE%


================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>org.blackdread</groupId>
    <artifactId>sql-to-java</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>sql-to-java</name>
    <description>Sql to JDL project</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>17</java.version>

        <database.url>jdbc:mysql://localhost:3306/?serverTimezone=UTC</database.url>
        <database.user>root</database.user>
        <database.password></database.password>

        <guava.version>33.3.1-jre</guava.version>

        <testcontainers.version>1.17.6</testcontainers.version>

        <!-- By default just re-write code with prettier -->
        <plugin.prettier.goal>write</plugin.prettier.goal>

        <maven.surefire.plugin.version>3.5.1</maven.surefire.plugin.version>
        <maven.checkstyle.plugin.version>3.5.0</maven.checkstyle.plugin.version>
        <liquibase-core.version>4.19.0</liquibase-core.version>
        <liquibase-maven-plugin.version>4.19.0</liquibase-maven-plugin.version>
        <checkstyle.version>10.18.2</checkstyle.version>
        <plugin.checkstyle.goal>check</plugin.checkstyle.goal>
<!--        <guava.version>31.1-jre</guava.version>-->
        <mustache.compiler.api.version>0.9.10</mustache.compiler.api.version>
        <org.mapstruct.version>1.6.2</org.mapstruct.version>
        <!--<jacoco-plugin.version>0.7.9</jacoco-plugin.version>-->
        <!--<coveralls-plugin.version>4.3.0</coveralls-plugin.version>-->
    </properties>

    <scm>
        <connection>scm:git:https://github.com/Blackdread/sql-to-jdl.git</connection>
        <developerConnection>scm:git:https://github.com/blackdread/sql-to-jdl.git</developerConnection>
        <url>https://github.com/blackdread/sql-to-jdl</url>
    </scm>

    <licenses>
        <license>
            <name>MIT</name>
            <url>https://github.com/Blackdread/sql-to-jdl/blob/master/LICENSE</url>
            <distribution>repo</distribution>
        </license>
    </licenses>

    <developers>
        <developer>
            <id>blackdread</id>
            <name>Yoann CAPLAIN</name>
            <email>yoann.caplain@blackdread.org</email>
            <url>http://blackdread.org</url>
        </developer>
    </developers>

    <dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.17.0</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.17.0</version>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>com.google.guava</groupId>-->
<!--            <artifactId>guava</artifactId>-->
<!--            <version>${guava.version}</version>-->
<!--        </dependency>-->

        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>12.4.2.jre11</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc11</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>

         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/uk.org.webcompere/system-stubs-core -->
        <dependency>
            <groupId>uk.org.webcompere</groupId>
            <artifactId>system-stubs-jupiter</artifactId>
            <version>2.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>testcontainers</artifactId>
            <version>${testcontainers.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${testcontainers.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>mysql</artifactId>
            <version>${testcontainers.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>mariadb</artifactId>
            <version>${testcontainers.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>mssqlserver</artifactId>
            <version>${testcontainers.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>postgresql</artifactId>
            <version>${testcontainers.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>oracle-xe</artifactId>
            <version>${testcontainers.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-core</artifactId>
            <version>${liquibase-core.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.github.spullara.mustache.java</groupId>
            <artifactId>compiler</artifactId>
            <version>${mustache.compiler.api.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
    </dependencies>

    <build>
        <defaultGoal>spring-boot:run</defaultGoal>
        <testResources>
            <testResource>
                <directory>src/test/resources/</directory>
            </testResource>
        </testResources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.plugin.version}</version>
                <configuration>
                  <forkCount>2.5C</forkCount>
                  <reuseForks>false</reuseForks>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.hubspot.maven.plugins</groupId>
                <artifactId>prettier-maven-plugin</artifactId>
                <version>0.22</version>
                <configuration>
                  <prettierJavaVersion>1.5.0</prettierJavaVersion>
                </configuration>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>${plugin.prettier.goal}</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
                <version>${maven.checkstyle.plugin.version}</version>
                <dependencies>
                    <dependency>
                        <groupId>com.puppycrawl.tools</groupId>
                        <artifactId>checkstyle</artifactId>
                        <version>${checkstyle.version}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <configLocation>checkstyle.xml</configLocation>
                    <suppressionsLocation>checkstyle-suppressions.xml</suppressionsLocation>
                </configuration>

            </plugin>
            <plugin>
                <groupId>org.liquibase</groupId>
                <artifactId>liquibase-maven-plugin</artifactId>
                <version>${liquibase-maven-plugin.version}</version>
                <configuration>
                    <propertyFileWillOverride>true</propertyFileWillOverride>
                    <propertyFile>src/test/resources/liquibase.properties</propertyFile>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
            <!--<plugin>-->
            <!--<groupId>org.jacoco</groupId>-->
            <!--<artifactId>jacoco-maven-plugin</artifactId>-->
            <!--<version>${jacoco-plugin.version}</version>-->
            <!--<executions>-->
            <!--<execution>-->
            <!--<id>prepare-agent</id>-->
            <!--<goals>-->
            <!--<goal>prepare-agent</goal>-->
            <!--</goals>-->
            <!--</execution>-->
            <!--</executions>-->
            <!--</plugin>-->
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>


</project>


================================================
FILE: src/main/java/org/blackdread/sqltojava/SqlToJavaApplication.java
================================================
package org.blackdread.sqltojava;

import java.util.List;
import org.blackdread.sqltojava.config.ApplicationProperties;
import org.blackdread.sqltojava.entity.JdlEntity;
import org.blackdread.sqltojava.service.logic.ExportService;
import org.blackdread.sqltojava.service.logic.JdlService;
import org.blackdread.sqltojava.service.logic.SqlService;
import org.blackdread.sqltojava.util.AppUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@EnableConfigurationProperties(ApplicationProperties.class)
@SpringBootApplication
public class SqlToJavaApplication implements CommandLineRunner {

    private static final Logger log = LoggerFactory.getLogger(SqlToJavaApplication.class);

    private final ApplicationProperties applicationProperties;

    private final SqlService sqlService;

    private final JdlService jdlService;

    private final ExportService exportService;

    public SqlToJavaApplication(
        final ApplicationProperties applicationProperties,
        final SqlService sqlService,
        final JdlService jdlService,
        final ExportService exportService
    ) {
        this.applicationProperties = applicationProperties;
        this.sqlService = sqlService;
        this.jdlService = jdlService;
        this.exportService = exportService;
    }

    public static void main(String[] args) {
        SpringApplication app = new SpringApplicationBuilder(SqlToJavaApplication.class).application();
        AppUtil.setup(app).run(args);
    }

    @Override
    public void run(final String... args) throws Exception {
        log.warn("Arguments passed: {}", args);
        final List<JdlEntity> entities = jdlService.buildEntities();

        exportService.export(entities);
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/config/ApplicationProperties.java
================================================
package org.blackdread.sqltojava.config;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.blackdread.sqltojava.entity.JdlFieldEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.boot.json.JsonParserFactory;
import org.springframework.util.ResourceUtils;

@ConstructorBinding
@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
public class ApplicationProperties {

    private static final Logger log = LoggerFactory.getLogger(ApplicationProperties.class);

    /**
     * Database name to export to JDL
     */
    private final String databaseToExport;
    private final List<String> databaseObjectPrefix;
    private final boolean addTableNameJdl;
    private final UndefinedJdlTypeHandlingEnum undefinedTypeHandling;
    private final DatabaseObjectTypesConfigEnum databaseObjectTypesConfig;
    private final Boolean renderEntitiesOnly;
    private final Boolean assumeBidirectional;
    private final List<String> ignoredTableNames;
    private final Export export;
    private final List<String> reservedList;
    private final Map<String, JdlFieldEnum> jdlTypeOverrides;

    @SuppressWarnings("unchecked")
    public ApplicationProperties(
        final String databaseToExport,
        final List<String> databaseObjectPrefix,
        final Boolean addTableNameJdl,
        final UndefinedJdlTypeHandlingEnum undefinedTypeHandling,
        final DatabaseObjectTypesConfigEnum databaseObjectTypesConfig,
        final Boolean renderEntitiesOnly,
        final Boolean assumeBidirectional,
        final List<String> ignoredTableNames,
        final Export export,
        final String reservedKeywords,
        final Map<String, JdlFieldEnum> jdlTypeOverrides
    ) {
        log.info("Loading ApplicationProperties...");
        this.databaseToExport = databaseToExport;
        this.databaseObjectPrefix = databaseObjectPrefix;
        this.undefinedTypeHandling = undefinedTypeHandling;
        this.databaseObjectTypesConfig = databaseObjectTypesConfig;
        this.renderEntitiesOnly = renderEntitiesOnly;
        this.assumeBidirectional = assumeBidirectional;
        this.addTableNameJdl = Optional.of(addTableNameJdl).orElse(false);
        this.ignoredTableNames = ignoredTableNames;
        this.export = export;
        this.reservedList =
            JsonParserFactory
                .getJsonParser()
                .parseMap(keywordsAsJson(reservedKeywords))
                .values()
                .stream()
                .map(obj -> (List<String>) obj)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
        this.jdlTypeOverrides = Optional.ofNullable(jdlTypeOverrides).orElse(Collections.emptyMap());
    }

    public String getDatabaseToExport() {
        return databaseToExport;
    }

    public List<String> getIgnoredTableNames() {
        return ignoredTableNames;
    }

    public Export getExport() {
        return export;
    }

    public List<String> getReservedList() {
        return reservedList;
    }

    public Boolean getAddTableNameJdl() {
        return addTableNameJdl;
    }

    public UndefinedJdlTypeHandlingEnum getUndefinedTypeHandling() {
        return undefinedTypeHandling;
    }

    public DatabaseObjectTypesConfigEnum getDatabaseObjectTypesConfig() {
        return databaseObjectTypesConfig;
    }

    public Boolean isRenderEntitiesOnly() {
        return renderEntitiesOnly;
    }

    public Boolean isAssumeBidirectional() {
        return assumeBidirectional;
    }

    public List<String> getDatabaseObjectPrefix() {
        return databaseObjectPrefix;
    }

    public Map<String, JdlFieldEnum> getJdlTypeOverrides() {
        return jdlTypeOverrides;
    }

    public static class Export {

        private final Path path;

        private final String type;
        private final ExportFileStructureType exportFileStructureType;
        private final String exportMustacheTemplateFilenameOptional;

        public Export(
            final Path path,
            final String type,
            ExportFileStructureType exportFileStructureType,
            String exportMustacheTemplateFilenameOptional
        ) {
            this.path = path;
            this.type = type;
            this.exportFileStructureType = exportFileStructureType;
            this.exportMustacheTemplateFilenameOptional = exportMustacheTemplateFilenameOptional;
        }

        public Path getPath() {
            return path;
        }

        public String getType() {
            return type;
        }

        public ExportFileStructureType getExportFileStructureType() {
            return exportFileStructureType;
        }

        public String getExportMustacheTemplateFilenameOptional() {
            return exportMustacheTemplateFilenameOptional;
        }
    }

    private String keywordsAsJson(String file) {
        try {
            Path path = ResourceUtils.getFile(file).toPath();
            return String.join(" ", Files.readAllLines(path));
        } catch (IOException e) {
            return "{\"key\": []}";
        }
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/config/CacheConfiguration.java
================================================
package org.blackdread.sqltojava.config;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching
public class CacheConfiguration {

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager();
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/config/DatabaseObjectTypesConfigEnum.java
================================================
package org.blackdread.sqltojava.config;

public enum DatabaseObjectTypesConfigEnum {
    TABLES,
    VIEWS,
    ALL,
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/config/ExportFileStructureType.java
================================================
package org.blackdread.sqltojava.config;

public enum ExportFileStructureType {
    SEPARATED("application", "Every entity, relationship are separated"),
    GROUPED_RELATIONS_SEPARATE_VIEWS(
        "application-grouped-relations-separate-views",
        "Relations are grouped by type, views  are separated from entites after entites and relations declarations"
    ),
    RELATIONS_BEFORE_VIEWS_SEPARATE_VIEWS(
        "application-entities-relations-views",
        "Relations are after entities and before views, views  are separated from entites after entites and relations declarations"
    );

    private final String exportMustacheTemplateFilename;
    private final String comment;

    ExportFileStructureType(String exportMustacheTemplateFilename, String comment) {
        this.exportMustacheTemplateFilename = exportMustacheTemplateFilename;
        this.comment = comment;
    }

    public String getExportMustacheTemplateFilename() {
        return exportMustacheTemplateFilename;
    }

    public String getComment() {
        return comment;
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/config/UndefinedJdlTypeHandlingEnum.java
================================================
package org.blackdread.sqltojava.config;

/**
 * Determines how undefined SQL column types ar handled
 */
public enum UndefinedJdlTypeHandlingEnum {
    /**
     * Throw an error
     */
    ERROR,

    /**
     * Skip writing the field to JDL
     */
    SKIP,

    /**
     * Write Unsupported as type and require manual cleanup
     */
    UNSUPPORTED,
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/JdlEntity.java
================================================
package org.blackdread.sqltojava.entity;

import java.util.List;
import java.util.Optional;

public interface JdlEntity {
    String getName();

    String getTableName();

    List<JdlField> getFields();

    /**
     * Add @readOnly to read only entity.
     * https://www.jhipster.tech/jdl/options
     */
    boolean isReadOnly();

    Optional<String> getComment();

    boolean isEnumEntity();

    /**
     * A pure ManyToMany entity only contains 2 columns of foreign keys
     *
     * @return True if this entity represent a pure ManyToMany relation of two other entities
     */
    boolean isPureManyToMany();

    /**
     * @return Relations where this entity is the owner side
     */
    List<JdlRelation> getRelations();
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/JdlField.java
================================================
package org.blackdread.sqltojava.entity;

import java.util.Optional;

public interface JdlField {
    JdlFieldEnum getType();

    String getName();

    /**
     * @return Entity name of the enum if this field is an enum value
     */
    Optional<String> getEnumEntityName();

    /**
     * Some DB support native enum (no use of extra table as an enum).
     * If is true then {@link #getEnumEntityName()} is not empty.
     *
     * @return true if field was created from a native enum column
     */
    boolean isNativeEnum();

    boolean isRequired();

    Optional<String> getComment();

    /**
     * Min of field (represent minLength if is a string)
     *
     * @return Min value of field
     */
    Optional<Integer> getMin();

    /**
     * Max of field (represent miaxength if is a string)
     *
     * @return Max value of field
     */
    Optional<Integer> getMax();

    Optional<String> getPattern();

    /**
     * @return - <code>true</code> if the column is marked as a unique column
     */
    boolean isUnique();

    /**
     * @return - <code>true</code> if the column is marked as a primary key column
     */
    boolean isPrimaryKey();
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/JdlFieldEnum.java
================================================
package org.blackdread.sqltojava.entity;

import com.google.common.base.CaseFormat;

public enum JdlFieldEnum {
    STRING,
    INTEGER,
    LONG,
    BIG_DECIMAL,
    FLOAT,
    DOUBLE,
    ENUM,
    BOOLEAN,
    LOCAL_DATE,
    ZONED_DATE_TIME,
    INSTANT,
    BLOB,
    ANY_BLOB,
    IMAGE_BLOB,
    TEXT_BLOB,

    /**
     * Used for native enums from DBs, values are defined in the DB so can be extracted.
     *
     * @deprecated not sure yet, this should be checked via extra methods and not a type
     */
    ENUM_NATIVE,

    /**
     * Defined here to allow to have a pattern set for TIME type of SQL that jdl does not support by default
     */
    TIME_AS_TEXT,
    /**
     * Defined here to allow to have a pattern set for YEAR type of SQL that jdl does not support by default
     */
    YEAR_AS_TEXT,
    /**
     * Defined here to allow to have a pattern set for GEOMETRY type of SQL that jdl does not support by default
     */
    GEOMETRY_AS_TEXT,
    /**
     * Defined here to allow to have a string without max length set for json type of SQL that jdl does not support by default
     */
    JSON_AS_TEXT,

    UUID,

    /**
     * Defined here to allow to have a string without max length set for postgres text type
     */
    STRING_UNBOUNDED,

    /**
     * Defined here to allow to jdl to generate with unsupported fields rather than failing with an error.
     */
    UNSUPPORTED;

    public String toCamelUpper() {
        return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, this.name());
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/JdlRelation.java
================================================
package org.blackdread.sqltojava.entity;

import java.util.Optional;

public interface JdlRelation {
    RelationType getRelationType();

    boolean isBidirectional();

    boolean isOwnerRequired();

    boolean isInverseSideRequired();

    //    boolean isMapsId();

    Optional<String> getOwnerComment();

    Optional<String> getInverseSideComment();

    /**
     * A comment that can be set to be displayed on top of the relation declaration, to help review the generated
     *
     * @return an extra comment
     */
    Optional<String> getComment();

    /**
     * OwnerSideEntityName{ownerRelationName(ownerDisplayField) required} to InverseSideEntityName{inverseSideRelationName(inverseSideDisplayField)}
     *
     * @return Entity name of owner side
     */
    String getOwnerEntityName();

    /**
     * OwnerSideEntityName{ownerRelationName(ownerDisplayField) required} to InverseSideEntityName{inverseSideRelationName(inverseSideDisplayField)}
     *
     * @return Entity name of inverse side
     */
    String getInverseSideEntityName();

    /**
     * @return Represent the "relationship name" on the owner side
     */
    String getOwnerRelationName();

    /**
     * OwnerSideEntityName{ownerRelationName(ownerDisplayField) required} to InverseSideEntityName{inverseSideRelationName(inverseSideDisplayField)}
     *
     * @return Represent the "relationship name" on the inverse side
     */
    Optional<String> getInverseSideRelationName();

    /**
     * OwnerSideEntityName{ownerRelationName(ownerDisplayField) required} to InverseSideEntityName{inverseSideRelationName(inverseSideDisplayField)}
     *
     * @return Represent the "display field name" on the owner side
     */
    Optional<String> getOwnerDisplayField();

    /**
     * OwnerSideEntityName{ownerRelationName(ownerDisplayField) required} to InverseSideEntityName{inverseSideRelationName(inverseSideDisplayField)}
     *
     * @return Represent the "display field name" on the inverse side
     */
    Optional<String> getInverseSideDisplayField();
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/JdlRelationGroup.java
================================================
package org.blackdread.sqltojava.entity;

import java.util.List;

public interface JdlRelationGroup {
    RelationType getRelationType();
    List<JdlRelation> getRelations();
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/RelationType.java
================================================
package org.blackdread.sqltojava.entity;

public enum RelationType {
    /**
     * @deprecated no reason to keep that, exception way before should happen
     */
    @Deprecated
    Unknown,
    /**
     * E.g: Can be known if sql column is unique
     */
    OneToOne,
    ManyToOne,
    ManyToMany;

    // OneToMany is not put as we always use ManyToOne

    public String toJdl() {
        return this.name();
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/SqlColumn.java
================================================
package org.blackdread.sqltojava.entity;

import java.util.Optional;

public interface SqlColumn {
    SqlTable getTable();

    /**
     * @return Column name
     */
    String getName();

    /**
     * Is usually a value of type and size like "type(size)"
     *
     * @return Column type
     */
    String getType();

    boolean isPrimaryKey();

    boolean isForeignKey();

    boolean isNullable();

    boolean isUnique();

    /**
     * Some DB support native enum (no use of extra table as an enum)
     *
     * @return true if column is a native enum
     */
    boolean isNativeEnum();

    Optional<String> getDefaultValue();

    Optional<String> getComment();
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/SqlForeignKey.java
================================================
package org.blackdread.sqltojava.entity;

public interface SqlForeignKey {}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/SqlTable.java
================================================
package org.blackdread.sqltojava.entity;

import java.util.Optional;

public interface SqlTable {
    String getName();
    Optional<String> getComment();
    boolean isUpdatable();
    String getType();
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/impl/JdlEntityImpl.java
================================================
package org.blackdread.sqltojava.entity.impl;

import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
import org.apache.commons.lang3.StringUtils;
import org.blackdread.sqltojava.entity.JdlEntity;
import org.blackdread.sqltojava.entity.JdlField;
import org.blackdread.sqltojava.entity.JdlRelation;

@Immutable
@ThreadSafe
public class JdlEntityImpl implements JdlEntity, Comparable<JdlEntity> {

    private final String name;

    private final String tableName;

    private final List<JdlField> fields;

    private final String comment;

    private final boolean readOnly;

    private final boolean enumEntity;

    private final boolean pureManyToMany;

    private final List<JdlRelation> relations;

    public JdlEntityImpl(
        final String name,
        final String tableName,
        final List<JdlField> fields,
        @Nullable final String comment,
        final boolean enumEntity,
        final boolean readOnly,
        final boolean pureManyToMany,
        final List<JdlRelation> relations
    ) {
        this.name = name;
        this.tableName = tableName;
        this.fields = ImmutableList.copyOf(fields);
        this.comment = (StringUtils.isBlank(comment) || "null".equalsIgnoreCase(comment)) ? null : comment;
        this.enumEntity = enumEntity;
        this.readOnly = readOnly;
        this.pureManyToMany = pureManyToMany;
        this.relations = ImmutableList.copyOf(relations);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getTableName() {
        return tableName;
    }

    @Override
    public List<JdlField> getFields() {
        return fields;
    }

    @Override
    public Optional<String> getComment() {
        return Optional.ofNullable(comment);
    }

    @Override
    public boolean isEnumEntity() {
        return enumEntity;
    }

    @Override
    public boolean isReadOnly() {
        return readOnly;
    }

    @Override
    public boolean isPureManyToMany() {
        return pureManyToMany;
    }

    @Override
    public List<JdlRelation> getRelations() {
        return relations;
    }

    @Override
    public String toString() {
        return (
            "JdlEntityImpl{" +
            "name='" +
            name +
            '\'' +
            "tableName='" +
            tableName +
            '\'' +
            ", fields=" +
            fields +
            ", comment='" +
            comment +
            '\'' +
            ", readOnly=" +
            readOnly +
            ", isEnum=" +
            enumEntity +
            ", relations=" +
            relations +
            '}'
        );
    }

    @Override
    public int compareTo(final JdlEntity o) {
        return name.compareTo(o.getName());
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/impl/JdlFieldImpl.java
================================================
package org.blackdread.sqltojava.entity.impl;

import java.util.Optional;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
import org.apache.commons.lang3.StringUtils;
import org.blackdread.sqltojava.entity.JdlField;
import org.blackdread.sqltojava.entity.JdlFieldEnum;

@Immutable
@ThreadSafe
public class JdlFieldImpl implements JdlField {

    private final JdlFieldEnum type;
    private final String name;
    private final String enumEntityName;
    private final boolean required;
    private final String comment;
    private final Integer min;
    private final Integer max;
    private final String pattern;
    private final Boolean nativeEnum;
    private final Boolean unique;
    private final Boolean primaryKey;

    public JdlFieldImpl(
        final JdlFieldEnum type,
        final String name,
        final boolean required,
        @Nullable final String comment,
        @Nullable final Integer min,
        @Nullable final Integer max,
        @Nullable final String pattern,
        @Nullable final String enumEntityName,
        final boolean nativeEnum,
        final boolean unique,
        final boolean primaryKey
    ) {
        this.type = type;
        this.name = name;
        this.required = required;
        this.comment = (StringUtils.isBlank(comment) || "null".equalsIgnoreCase(comment)) ? null : comment;
        this.min = min;
        this.max = max;
        this.pattern = pattern;
        this.enumEntityName = enumEntityName;
        this.nativeEnum = nativeEnum;
        this.unique = unique;
        this.primaryKey = primaryKey;
    }

    @Override
    public JdlFieldEnum getType() {
        return type;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public Optional<String> getEnumEntityName() {
        return Optional.ofNullable(enumEntityName);
    }

    @Override
    public boolean isRequired() {
        return required;
    }

    @Override
    public Optional<String> getComment() {
        return Optional.ofNullable(comment);
    }

    @Override
    public Optional<Integer> getMin() {
        return Optional.ofNullable(min);
    }

    @Override
    public Optional<Integer> getMax() {
        return Optional.ofNullable(max);
    }

    @Override
    public Optional<String> getPattern() {
        return Optional.ofNullable(pattern);
    }

    @Override
    public boolean isUnique() {
        return unique;
    }

    @Override
    public boolean isPrimaryKey() {
        return primaryKey;
    }

    @Override
    public boolean isNativeEnum() {
        return nativeEnum;
    }

    @Override
    public String toString() {
        return (
            "JdlFieldImpl{" +
            "type=" +
            type +
            ", name='" +
            name +
            '\'' +
            ", enumEntityName='" +
            enumEntityName +
            '\'' +
            ", isRequired=" +
            required +
            ", comment='" +
            comment +
            '\'' +
            ", min=" +
            min +
            ", max=" +
            max +
            ", pattern='" +
            pattern +
            '\'' +
            ", isNativeEnum=" +
            nativeEnum +
            '}'
        );
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/impl/JdlRelationGroupImpl.java
================================================
package org.blackdread.sqltojava.entity.impl;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
import org.blackdread.sqltojava.entity.JdlRelation;
import org.blackdread.sqltojava.entity.JdlRelationGroup;
import org.blackdread.sqltojava.entity.RelationType;

@Immutable
@ThreadSafe
public class JdlRelationGroupImpl implements JdlRelationGroup, Comparable<JdlRelationGroup> {

    private final RelationType relationType;
    private final List<JdlRelation> relations;

    public JdlRelationGroupImpl(RelationType relationType, List<JdlRelation> relations) {
        this.relationType = relationType;
        this.relations = relations;
    }

    public RelationType getRelationType() {
        return relationType;
    }

    public List<JdlRelation> getRelations() {
        return relations;
    }

    @Override
    public int compareTo(final JdlRelationGroup o) {
        return this.relationType.compareTo(o.getRelationType());
    }

    @Override
    public String toString() {
        return (
            "JdlRelationGroupImpl{" +
            "relationType=" +
            relationType +
            ", relations=" +
            relations.stream().map(e -> e.getOwnerEntityName()).collect(Collectors.joining()) +
            '}'
        );
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/impl/JdlRelationImpl.java
================================================
package org.blackdread.sqltojava.entity.impl;

import java.util.Optional;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
import org.apache.commons.lang3.StringUtils;
import org.blackdread.sqltojava.entity.JdlRelation;
import org.blackdread.sqltojava.entity.RelationType;

@Immutable
@ThreadSafe
public class JdlRelationImpl implements JdlRelation, Comparable<JdlRelation> {

    private final RelationType relationType;

    private final boolean bidirectional;
    private final boolean ownerRequired;
    private final boolean inverseSideRequired;

    private final String ownerEntityName;
    private final String inverseSideEntityName;

    private final String ownerRelationName;
    private final String ownerDisplayField;

    private final String ownerComment;
    private final String inverseSideComment;
    private final String inverseSideRelationName;
    private final String inverseSideDisplayField;

    private final String comment;

    public JdlRelationImpl(
        final RelationType relationType,
        final boolean bidirectional,
        final boolean ownerRequired,
        final boolean inverseSideRequired,
        final String ownerEntityName,
        final String inverseSideEntityName,
        final String ownerRelationName,
        @Nullable final String ownerDisplayField,
        @Nullable final String ownerComment,
        @Nullable final String inverseSideComment,
        @Nullable final String inverseSideRelationName,
        @Nullable final String inverseSideDisplayField,
        @Nullable final String comment
    ) {
        this.relationType = relationType;
        this.bidirectional = bidirectional;
        this.ownerRequired = ownerRequired;
        this.inverseSideRequired = inverseSideRequired;

        this.ownerEntityName = ownerEntityName;
        this.inverseSideEntityName = inverseSideEntityName;

        this.ownerRelationName = ownerRelationName;
        this.ownerDisplayField =
            (StringUtils.isBlank(ownerDisplayField) || "null".equalsIgnoreCase(ownerDisplayField)) ? null : ownerDisplayField;

        this.ownerComment = (StringUtils.isBlank(ownerComment) || "null".equalsIgnoreCase(ownerComment)) ? null : ownerComment;
        this.inverseSideComment =
            (StringUtils.isBlank(inverseSideComment) || "null".equalsIgnoreCase(inverseSideComment)) ? null : inverseSideComment;
        this.inverseSideRelationName =
            (StringUtils.isBlank(inverseSideRelationName) || "null".equalsIgnoreCase(inverseSideRelationName))
                ? null
                : inverseSideRelationName;
        this.inverseSideDisplayField =
            (StringUtils.isBlank(inverseSideDisplayField) || "null".equalsIgnoreCase(inverseSideDisplayField))
                ? null
                : inverseSideDisplayField;
        this.comment = (StringUtils.isBlank(comment) || "null".equalsIgnoreCase(comment)) ? null : comment;
    }

    @Override
    public RelationType getRelationType() {
        return relationType;
    }

    @Override
    public boolean isBidirectional() {
        return bidirectional;
    }

    @Override
    public boolean isOwnerRequired() {
        return ownerRequired;
    }

    @Override
    public boolean isInverseSideRequired() {
        return inverseSideRequired;
    }

    @Override
    public Optional<String> getOwnerComment() {
        return Optional.ofNullable(ownerComment);
    }

    @Override
    public Optional<String> getInverseSideComment() {
        return Optional.ofNullable(inverseSideComment);
    }

    @Override
    public Optional<String> getComment() {
        return Optional.ofNullable(comment);
    }

    @Override
    public String getOwnerEntityName() {
        return ownerEntityName;
    }

    @Override
    public String getInverseSideEntityName() {
        return inverseSideEntityName;
    }

    @Override
    public String getOwnerRelationName() {
        return ownerRelationName;
    }

    @Override
    public Optional<String> getInverseSideRelationName() {
        return Optional.ofNullable(inverseSideRelationName);
    }

    @Override
    public Optional<String> getOwnerDisplayField() {
        return Optional.ofNullable(ownerDisplayField);
    }

    @Override
    public Optional<String> getInverseSideDisplayField() {
        return Optional.ofNullable(inverseSideDisplayField);
    }

    @Override
    public int compareTo(final JdlRelation o) {
        return this.ownerEntityName.compareTo(o.getOwnerEntityName());
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/impl/SqlColumnImpl.java
================================================
package org.blackdread.sqltojava.entity.impl;

import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import org.blackdread.sqltojava.entity.SqlColumn;
import org.blackdread.sqltojava.entity.SqlTable;

public class SqlColumnImpl implements SqlColumn {

    private final SqlTable table;

    private final String name;

    private final String type;

    private final boolean isPrimaryKey;

    private final boolean isForeignKey;

    private final boolean isNullable;

    private final boolean isUnique;

    private final boolean isNativeEnum;

    private final String defaultValue;

    private final String comment;

    public SqlColumnImpl(
        final SqlTable table,
        final String name,
        final String type,
        final boolean isPrimaryKey,
        final boolean isForeignKey,
        final boolean isNullable,
        final boolean isUnique,
        final boolean isNativeEnum,
        @Nullable final String defaultValue,
        final String comment
    ) {
        this.table = table;
        this.name = name;
        this.type = type;
        this.isPrimaryKey = isPrimaryKey;
        this.isForeignKey = isForeignKey;
        this.isNullable = isNullable;
        this.isUnique = isUnique;
        this.isNativeEnum = isNativeEnum;
        this.defaultValue = (StringUtils.isBlank(defaultValue) || "null".equalsIgnoreCase(comment)) ? null : defaultValue;
        this.comment = (StringUtils.isBlank(comment) || "null".equalsIgnoreCase(comment)) ? null : comment;
    }

    @Override
    public SqlTable getTable() {
        return table;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getType() {
        return type;
    }

    @Override
    public boolean isPrimaryKey() {
        return isPrimaryKey;
    }

    @Override
    public boolean isForeignKey() {
        return isForeignKey;
    }

    @Override
    public boolean isNullable() {
        return isNullable;
    }

    @Override
    public boolean isUnique() {
        return isUnique;
    }

    @Override
    public boolean isNativeEnum() {
        return isNativeEnum;
    }

    @Override
    public Optional<String> getDefaultValue() {
        return Optional.ofNullable(defaultValue);
    }

    @Override
    public Optional<String> getComment() {
        return Optional.ofNullable(comment);
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        final SqlColumnImpl sqlColumn = (SqlColumnImpl) o;
        return (Objects.equals(table, sqlColumn.table) && Objects.equals(name, sqlColumn.name) && Objects.equals(type, sqlColumn.type));
    }

    @Override
    public int hashCode() {
        return Objects.hash(table, name, type);
    }

    @Override
    public String toString() {
        return (
            "SqlColumnImpl{" +
            "table=" +
            table +
            ", name='" +
            name +
            '\'' +
            ", type='" +
            type +
            '\'' +
            ", isPrimaryKey=" +
            isPrimaryKey +
            ", isForeignKey=" +
            isForeignKey +
            ", isNullable=" +
            isNullable +
            ", isUnique=" +
            isUnique +
            ", isNativeEnum=" +
            isNativeEnum +
            ", defaultValue='" +
            defaultValue +
            '\'' +
            ", comment='" +
            comment +
            '\'' +
            '}'
        );
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/entity/impl/SqlTableImpl.java
================================================
package org.blackdread.sqltojava.entity.impl;

import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import org.blackdread.sqltojava.entity.SqlTable;

public class SqlTableImpl implements SqlTable, Comparable<SqlTable> {

    private final String name;
    private final String comment;
    private final boolean isUpdateable;
    private final String type;

    public SqlTableImpl(final String name, @Nullable final String comment, final String type, final boolean isUpdateable) {
        this.name = Objects.requireNonNull(name);
        this.comment = (StringUtils.isBlank(comment) || "null".equalsIgnoreCase(comment)) ? null : comment;
        this.type = type;
        this.isUpdateable = isUpdateable;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public Optional<String> getComment() {
        return Optional.ofNullable(comment);
    }

    @Override
    public String getType() {
        return type;
    }

    @Override
    public boolean isUpdatable() {
        return isUpdateable;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        final SqlTableImpl sqlTable = (SqlTableImpl) o;
        return Objects.equals(name, sqlTable.name);
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }

    @Override
    public String toString() {
        return ("SqlTableImpl{" + "name='" + name + '\'' + ", comment='" + comment + '\'' + '}');
    }

    @Override
    public int compareTo(final SqlTable o) {
        return name.compareTo(o.getName());
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/exporter/ExportFileStructureConfig.java
================================================
package org.blackdread.sqltojava.exporter;

import org.apache.commons.lang3.StringUtils;
import org.blackdread.sqltojava.config.ApplicationProperties;
import org.blackdread.sqltojava.config.ExportFileStructureType;
import org.springframework.stereotype.Service;

@Service
public class ExportFileStructureConfig {

    private final ApplicationProperties applicationProperties;
    private ExportFileStructureType exportFileStructureType;
    private String exportMustacheTemplateFilename;

    public ExportFileStructureConfig(ApplicationProperties applicationProperties) {
        this.applicationProperties = applicationProperties;
        exportFileStructureType = applicationProperties.getExport().getExportFileStructureType();
        String newTemplateName = applicationProperties.getExport().getExportMustacheTemplateFilenameOptional();
        exportMustacheTemplateFilename =
            StringUtils.isBlank(newTemplateName) ? exportFileStructureType.getExportMustacheTemplateFilename() : newTemplateName;
    }

    public String getExportMustacheTemplateFilename() {
        return exportMustacheTemplateFilename;
    }

    public ExportFileStructureType getExportFileStructureType() {
        return exportFileStructureType;
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/listener/SetDatabaseProfileApplicationEventListener.java
================================================
package org.blackdread.sqltojava.listener;

import org.blackdread.sqltojava.util.JdbcUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;

public class SetDatabaseProfileApplicationEventListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {

    private static final Logger log = LoggerFactory.getLogger(SetDatabaseProfileApplicationEventListener.class);

    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent e) {
        ConfigurableEnvironment env = e.getEnvironment();
        String[] activeProfiles = env.getActiveProfiles();

        if (activeProfiles.length == 0) {
            String jdbcUrl = env.getProperty("spring.datasource.url");
            String profileName = JdbcUtil.getDatabaseTypeFromJdbcUrl(jdbcUrl);
            log.debug(String.format("No active profiles using %s from %s", profileName, jdbcUrl));
            env.setActiveProfiles(profileName);
        } else {
            log.debug(String.format("Active profile %s found.  Automatic setting from spring.datasource.url disabled.", activeProfiles));
        }
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/parser/SqlParser.java
================================================
package org.blackdread.sqltojava.parser;

import com.google.common.io.Files;
import java.io.File;

public class SqlParser {

    /**
     * @param fileToParse Sql file
     * @param saveInto    Jdl file to save into
     */
    public static void parse(final File fileToParse, final File saveInto) {
        checkIsSql(fileToParse);
    }

    private static void checkIsSql(final File file) {
        final String fileExtension = Files.getFileExtension(file.getName());
        if (!fileExtension.equalsIgnoreCase("sql")) {
            throw new IllegalArgumentException("Not an sql file");
        }
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/pojo/ColumnInformation.java
================================================
package org.blackdread.sqltojava.pojo;

import java.util.Optional;
import org.apache.commons.lang3.StringUtils;

public class ColumnInformation {

    private final String name;
    private final String type;
    private final boolean isNullable;
    private final boolean isPrimary;
    private final boolean isUnique;
    private final String defaultValue;
    private final int ordinalPosition;
    private final String comment;

    public ColumnInformation(
        final String name,
        final String type,
        final boolean isNullable,
        final boolean isPrimary,
        final boolean isUnique,
        final String defaultValue,
        final int ordinalPosition,
        final String comment
    ) {
        this.name = name;
        this.type = type;
        this.isNullable = isNullable;
        this.isPrimary = isPrimary;
        this.isUnique = isUnique;
        if (StringUtils.isBlank(defaultValue) || "null".equalsIgnoreCase(defaultValue)) {
            this.defaultValue = null;
        } else {
            this.defaultValue = defaultValue;
        }
        this.ordinalPosition = ordinalPosition;
        this.comment = comment;
    }

    public ColumnInformation(
        final String name,
        final String type,
        final String nullValue,
        final String keyValue,
        final String defaultValue,
        int ordinalPosition,
        final String comment
    ) {
        this(
            name,
            type,
            "yes".equalsIgnoreCase(nullValue),
            "pri".equalsIgnoreCase(keyValue),
            "uni".equalsIgnoreCase(keyValue),
            defaultValue,
            ordinalPosition,
            comment
        );
    }

    public String getName() {
        return name;
    }

    public String getType() {
        return type;
    }

    public boolean isNullable() {
        return isNullable;
    }

    public boolean isPrimary() {
        return isPrimary;
    }

    public boolean isUnique() {
        return isUnique;
    }

    public Optional<String> getDefaultValue() {
        return Optional.ofNullable(defaultValue);
    }

    public int getOrdinalPosition() {
        return ordinalPosition;
    }

    public String getComment() {
        return comment;
    }

    @Override
    public String toString() {
        return (
            "ColumnInformation{" +
            "name='" +
            name +
            '\'' +
            ", type='" +
            type +
            '\'' +
            ", isNullable=" +
            isNullable +
            ", isPrimary=" +
            isPrimary +
            ", isUnique=" +
            isUnique +
            ", defaultValue='" +
            defaultValue +
            '\'' +
            ", comment='" +
            comment +
            '\'' +
            '}'
        );
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/pojo/TableInformation.java
================================================
package org.blackdread.sqltojava.pojo;

import java.util.Objects;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;

public class TableInformation {

    private String schema;
    private final String name;
    private final String comment;
    private final boolean isUpdateable;
    private final String type;

    public TableInformation(final String name, final boolean isUpdateable, String type, final String comment) {
        this.name = name;
        this.isUpdateable = isUpdateable;
        this.comment = (StringUtils.isBlank(comment) || "null".equalsIgnoreCase(comment)) ? null : comment;
        this.type = type;
    }

    public String getName() {
        return name;
    }

    public Optional<String> getComment() {
        return Optional.ofNullable(comment);
    }

    public String getSchema() {
        return schema;
    }

    public Boolean isUpdateable() {
        return isUpdateable;
    }

    public String getType() {
        return type;
    }

    @Override
    public String toString() {
        return ("TableInformation{" + "name='" + name + '\'' + ", comment='" + comment + '\'' + '}');
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        final TableInformation that = (TableInformation) o;
        return Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/pojo/TableRelationInformation.java
================================================
package org.blackdread.sqltojava.pojo;

import java.util.Objects;

public class TableRelationInformation {

    private final String tableName;
    private final String columnName;
    private final String referencedTableName;
    private final String referencedColumnName;

    public TableRelationInformation(
        final String tableName,
        final String columnName,
        final String referencedTableName,
        final String referencedColumnName
    ) {
        this.tableName = tableName;
        this.columnName = columnName;
        this.referencedTableName = referencedTableName;
        this.referencedColumnName = referencedColumnName;
    }

    public String getTableName() {
        return tableName;
    }

    public String getColumnName() {
        return columnName;
    }

    public String getReferencedTableName() {
        return referencedTableName;
    }

    public String getReferencedColumnName() {
        return referencedColumnName;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        final TableRelationInformation that = (TableRelationInformation) o;
        return (
            Objects.equals(tableName, that.tableName) &&
            Objects.equals(columnName, that.columnName) &&
            Objects.equals(referencedTableName, that.referencedTableName) &&
            Objects.equals(referencedColumnName, that.referencedColumnName)
        );
    }

    @Override
    public int hashCode() {
        return Objects.hash(tableName, columnName, referencedTableName, referencedColumnName);
    }

    @Override
    public String toString() {
        return (
            "TableRelationInformation{" +
            "tableName='" +
            tableName +
            '\'' +
            ", columnName='" +
            columnName +
            '\'' +
            ", referencedTableName='" +
            referencedTableName +
            '\'' +
            ", referencedColumnName='" +
            referencedColumnName +
            '\'' +
            '}'
        );
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/pojo/rowmaper/ColumnInformationRowMapper.java
================================================
package org.blackdread.sqltojava.pojo.rowmaper;

import java.sql.ResultSet;
import java.sql.SQLException;
import org.blackdread.sqltojava.pojo.ColumnInformation;
import org.springframework.jdbc.core.RowMapper;

public class ColumnInformationRowMapper implements RowMapper<ColumnInformation> {

    @Override
    public ColumnInformation mapRow(ResultSet rs, int rowNum) throws SQLException {
        return new ColumnInformation(
            rs.getString("column_name"),
            rs.getString("data_type"),
            rs.getString("is_nullable"),
            rs.getString("key"),
            rs.getString("column_default"),
            rs.getInt("ordinal_position"),
            rs.getString("comment")
        );
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/pojo/rowmaper/SqlServerColumnInformationRowMapper.java
================================================
package org.blackdread.sqltojava.pojo.rowmaper;

import java.sql.ResultSet;
import java.sql.SQLException;
import org.blackdread.sqltojava.pojo.ColumnInformation;
import org.springframework.jdbc.core.RowMapper;

public class SqlServerColumnInformationRowMapper implements RowMapper<ColumnInformation> {

    @Override
    public ColumnInformation mapRow(ResultSet rs, int rowNum) throws SQLException {
        return new ColumnInformation(
            rs.getString("column_name"),
            rs.getString("data_type"),
            rs.getString("is_nullable"),
            rs.getString("keye"),
            rs.getString("column_default"),
            rs.getInt("ordinal_position"),
            ""
        );
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/pojo/rowmaper/SqlServerTableInformationRowMapper.java
================================================
package org.blackdread.sqltojava.pojo.rowmaper;

import java.sql.ResultSet;
import java.sql.SQLException;
import org.blackdread.sqltojava.pojo.TableInformation;
import org.springframework.jdbc.core.RowMapper;

public class SqlServerTableInformationRowMapper implements RowMapper<TableInformation> {

    @Override
    public TableInformation mapRow(ResultSet rs, int rowNum) throws SQLException {
        return new TableInformation(
            rs.getString("table_name"),
            rs.getBoolean("updateable"),
            rs.getString("table_type"),
            rs.getString("comment")
        );
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/pojo/rowmaper/TableInformationRowMapper.java
================================================
package org.blackdread.sqltojava.pojo.rowmaper;

import java.sql.ResultSet;
import java.sql.SQLException;
import org.blackdread.sqltojava.pojo.TableInformation;
import org.springframework.jdbc.core.RowMapper;

public class TableInformationRowMapper implements RowMapper<TableInformation> {

    @Override
    public TableInformation mapRow(ResultSet rs, int rowNum) throws SQLException {
        return new TableInformation(
            rs.getString("table_name"),
            rs.getBoolean("is_updatable"),
            rs.getString("table_type"),
            rs.getString("comment")
        );
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/pojo/rowmaper/TableRelationInformationRowMapper.java
================================================
package org.blackdread.sqltojava.pojo.rowmaper;

import java.sql.ResultSet;
import java.sql.SQLException;
import org.blackdread.sqltojava.pojo.TableRelationInformation;
import org.springframework.jdbc.core.RowMapper;

public class TableRelationInformationRowMapper implements RowMapper<TableRelationInformation> {

    @Override
    public TableRelationInformation mapRow(ResultSet rs, int rowNum) throws SQLException {
        return new TableRelationInformation(
            rs.getString("table_name"),
            rs.getString("column_name"),
            rs.getString("foreign_table_name"),
            rs.getString("foreign_column_name")
        );
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/repository/InformationSchemaRepository.java
================================================
package org.blackdread.sqltojava.repository;

import java.util.List;
import org.blackdread.sqltojava.pojo.ColumnInformation;
import org.blackdread.sqltojava.pojo.TableInformation;
import org.blackdread.sqltojava.pojo.TableRelationInformation;

public interface InformationSchemaRepository {
    List<TableRelationInformation> getAllTableRelationInformation(final String dbName);
    List<ColumnInformation> getFullColumnInformationOfTable(final String dbName, final String tableName);
    List<TableInformation> getAllTableInformation(final String dbName);
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/repository/MsSqlPureSqlInformationSchemaRepository.java
================================================
package org.blackdread.sqltojava.repository;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.blackdread.sqltojava.pojo.ColumnInformation;
import org.blackdread.sqltojava.pojo.TableInformation;
import org.blackdread.sqltojava.pojo.TableRelationInformation;
import org.blackdread.sqltojava.pojo.rowmaper.SqlServerColumnInformationRowMapper;
import org.blackdread.sqltojava.pojo.rowmaper.SqlServerTableInformationRowMapper;
import org.blackdread.sqltojava.pojo.rowmaper.TableRelationInformationRowMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
@Profile({ "sqlserver" })
public class MsSqlPureSqlInformationSchemaRepository implements InformationSchemaRepository {

    private static final Logger log = LoggerFactory.getLogger(MsSqlPureSqlInformationSchemaRepository.class);
    private static String ALL_TABLE_RELATIONAL_INFROMATION;
    private static String FULL_COLUMN_INFORMATION_OF_TABLE;
    private static String ALL_TABLE_INFORMATION;
    private static final SqlServerTableInformationRowMapper TABLE_INFORMATION_MAPPER = new SqlServerTableInformationRowMapper();
    private final NamedParameterJdbcTemplate template;

    @Autowired
    public MsSqlPureSqlInformationSchemaRepository(NamedParameterJdbcTemplate template, ConfigurableEnvironment env) {
        String activeProfile = env.getActiveProfiles()[0];
        ALL_TABLE_RELATIONAL_INFROMATION = readSqlFileByProfile(activeProfile, "getAllTableRelationInformation");
        FULL_COLUMN_INFORMATION_OF_TABLE = readSqlFileByProfile(activeProfile, "getFullColumnInformationOfTable");
        ALL_TABLE_INFORMATION = readSqlFileByProfile(activeProfile, "getAllTableInformation");
        this.template = template;
    }

    @Override
    public List<TableRelationInformation> getAllTableRelationInformation(final String schemaName) {
        Map<String, ?> paramMap = Map.of("schemaName", schemaName);
        return template.queryForStream(ALL_TABLE_RELATIONAL_INFROMATION, paramMap, new TableRelationInformationRowMapper()).toList();
    }

    @Override
    public List<ColumnInformation> getFullColumnInformationOfTable(final String schemaName, final String tableName) {
        Map<String, ?> paramMap = Map.of("schemaName", schemaName, "tableName", tableName);
        return template.queryForStream(FULL_COLUMN_INFORMATION_OF_TABLE, paramMap, new SqlServerColumnInformationRowMapper()).toList();
    }

    public List<TableInformation> getAllTableInformation(final String schemaName) {
        Map<String, ?> paramMap = Map.of("schemaName", schemaName);
        return template.queryForStream(ALL_TABLE_INFORMATION, paramMap, TABLE_INFORMATION_MAPPER).toList();
    }

    /**
     * Loads a sql query file based on the active profile.
     * For multiple profiles to use the same sql files they should be named as follows:
     * sql/{profile1}_{profile1}-{queryName}.sql
     * See mysql_mariadb-queryName.sql for an example.
     * @param activeProfile
     * @param queryName
     * @return
     */
    private String readSqlFileByProfile(String activeProfile, String queryName) {
        ClassLoader cl = this.getClass().getClassLoader();
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
        String pattern = String.format("classpath*:/sql/*%s*-%s.sql", activeProfile, queryName);
        log.info("Using pattern " + pattern);
        try {
            Resource[] resources = resolver.getResources(pattern);
            if (resources.length != 1) {
                throw new IllegalArgumentException(String.format("Found %s when 1 was expected", resources.length));
            }
            Resource r = resources[0];
            log.info("Found resource " + r.getFilename());

            Resource resource = new ClassPathResource("sql/" + r.getFilename());
            InputStream inputStream = resource.getInputStream();

            try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
                return reader.lines().collect(Collectors.joining("\n"));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            //            return ResourceUtil.readString(r);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/repository/PureSqlInformationSchemaRepository.java
================================================
package org.blackdread.sqltojava.repository;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.blackdread.sqltojava.pojo.ColumnInformation;
import org.blackdread.sqltojava.pojo.TableInformation;
import org.blackdread.sqltojava.pojo.TableRelationInformation;
import org.blackdread.sqltojava.pojo.rowmaper.ColumnInformationRowMapper;
import org.blackdread.sqltojava.pojo.rowmaper.TableInformationRowMapper;
import org.blackdread.sqltojava.pojo.rowmaper.TableRelationInformationRowMapper;
import org.blackdread.sqltojava.util.ResourceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
@Profile({ "mysql", "mariadb", "postgresql", "oracle" })
public class PureSqlInformationSchemaRepository implements InformationSchemaRepository {

    private static final Logger log = LoggerFactory.getLogger(PureSqlInformationSchemaRepository.class);
    private static String ALL_TABLE_RELATIONAL_INFROMATION;
    private static String FULL_COLUMN_INFORMATION_OF_TABLE;
    private static String ALL_TABLE_INFORMATION;
    private static final TableInformationRowMapper TABLE_INFORMATION_MAPPER = new TableInformationRowMapper();
    private final NamedParameterJdbcTemplate template;

    @Autowired
    public PureSqlInformationSchemaRepository(NamedParameterJdbcTemplate template, ConfigurableEnvironment env) {
        String activeProfile = env.getActiveProfiles()[0];
        ALL_TABLE_RELATIONAL_INFROMATION = readSqlFileByProfile(activeProfile, "getAllTableRelationInformation");
        FULL_COLUMN_INFORMATION_OF_TABLE = readSqlFileByProfile(activeProfile, "getFullColumnInformationOfTable");
        ALL_TABLE_INFORMATION = readSqlFileByProfile(activeProfile, "getAllTableInformation");
        this.template = template;
    }

    @Override
    public List<TableRelationInformation> getAllTableRelationInformation(final String schemaName) {
        Map<String, ?> paramMap = Map.of("schemaName", schemaName);
        return template.queryForStream(ALL_TABLE_RELATIONAL_INFROMATION, paramMap, new TableRelationInformationRowMapper()).toList();
    }

    @Override
    public List<ColumnInformation> getFullColumnInformationOfTable(final String schemaName, final String tableName) {
        Map<String, ?> paramMap = Map.of("schemaName", schemaName, "tableName", tableName);
        return template.queryForStream(FULL_COLUMN_INFORMATION_OF_TABLE, paramMap, new ColumnInformationRowMapper()).toList();
    }

    public List<TableInformation> getAllTableInformation(final String schemaName) {
        Map<String, ?> paramMap = Map.of("schemaName", schemaName);
        return template.queryForStream(ALL_TABLE_INFORMATION, paramMap, TABLE_INFORMATION_MAPPER).toList();
    }

    /**
     * Loads a sql query file based on the active profile.
     * For multiple profiles to use the same sql files they should be named as follows:
     * sql/{profile1}_{profile1}-{queryName}.sql
     * See mysql_mariadb-queryName.sql for an example.
     * @param activeProfile
     * @param queryName
     * @return
     */
    private String readSqlFileByProfile(String activeProfile, String queryName) {
        ClassLoader cl = this.getClass().getClassLoader();
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
        String pattern = String.format("classpath*:/sql/*%s*-%s.sql", activeProfile, queryName);
        log.info("Using pattern " + pattern);
        try {
            Resource[] resources = resolver.getResources(pattern);
            if (resources.length != 1) {
                throw new IllegalArgumentException(String.format("Found %s when 1 was expected", resources.length));
            }
            Resource r = resources[0];
            log.info("Found resource " + r.getFilename());
            return ResourceUtil.readString(r);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/service/InformationSchemaService.java
================================================
package org.blackdread.sqltojava.service;

import java.util.List;
import org.blackdread.sqltojava.config.ApplicationProperties;
import org.blackdread.sqltojava.pojo.ColumnInformation;
import org.blackdread.sqltojava.pojo.TableInformation;
import org.blackdread.sqltojava.pojo.TableRelationInformation;
import org.blackdread.sqltojava.repository.InformationSchemaRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
public class InformationSchemaService {

    private static final Logger log = LoggerFactory.getLogger(InformationSchemaService.class);

    private final ApplicationProperties applicationProperties;

    private final InformationSchemaRepository informationSchemaRepository;

    public InformationSchemaService(
        final ApplicationProperties applicationProperties,
        final InformationSchemaRepository informationSchemaRepository
    ) {
        this.applicationProperties = applicationProperties;
        this.informationSchemaRepository = informationSchemaRepository;
    }

    @Cacheable("InformationSchemaService.getAllTableRelationInformation")
    public List<TableRelationInformation> getAllTableRelationInformation() {
        log.debug("getAllTableRelationInformation called");
        return informationSchemaRepository.getAllTableRelationInformation(applicationProperties.getDatabaseToExport());
    }

    @Cacheable("InformationSchemaService.getFullColumnInformationOfTable")
    public List<ColumnInformation> getFullColumnInformationOfTable(final String tableName) {
        log.debug("getFullColumnInformationOfTable called for table: {}", tableName);
        return informationSchemaRepository.getFullColumnInformationOfTable(applicationProperties.getDatabaseToExport(), tableName);
    }

    @Cacheable("InformationSchemaService.getAllTableInformation")
    public List<TableInformation> getAllTableInformation() {
        log.debug("getAllTableInformation called");
        return informationSchemaRepository.getAllTableInformation(applicationProperties.getDatabaseToExport());
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/service/MsSqlJdlTypeService.java
================================================
package org.blackdread.sqltojava.service;

import static java.util.Map.entry;
import static org.blackdread.sqltojava.entity.JdlFieldEnum.*;
import static org.blackdread.sqltojava.entity.JdlFieldEnum.UUID;
import static org.blackdread.sqltojava.util.SqlUtils.COLUMN_TYPE_SIZE_REGEX;

import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.blackdread.sqltojava.config.ApplicationProperties;
import org.blackdread.sqltojava.entity.JdlFieldEnum;
import org.blackdread.sqltojava.entity.SqlColumn;
import org.blackdread.sqltojava.util.SqlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Service
@Profile("sqlserver")
public class MsSqlJdlTypeService implements SqlJdlTypeService {

    private static final Logger log = LoggerFactory.getLogger(MsSqlJdlTypeService.class);
    public static final int VARCHAR_MAX_LENGTH = 8000;
    public static final int NVARCHAR_MAX_LENGTH = 4000;
    public static final int COLUMN_TYPE_MAX_LENGTH_MAX_VALUE = -1;

    private final ApplicationProperties properties;

    public MsSqlJdlTypeService(ApplicationProperties properties) {
        this.properties = properties;
    }

    private final Map<String, JdlFieldEnum> typeMap = Map.ofEntries(
        entry("bit", BOOLEAN),
        entry("date", LOCAL_DATE),
        entry("time", TIME_AS_TEXT),
        entry("datetime", INSTANT),
        entry("datetime2", INSTANT),
        entry("smalldatetime", INSTANT),
        entry("datetimeoffset", ZONED_DATE_TIME),
        entry("real", FLOAT),
        entry("float", DOUBLE),
        entry("smallint", INTEGER),
        entry("int", INTEGER),
        entry("bigint", LONG),
        entry("tinyint", INTEGER),
        entry("money", BIG_DECIMAL),
        entry("numeric", BIG_DECIMAL),
        entry("decimal", BIG_DECIMAL),
        entry("char", STRING), //char(max) is string with length up to 8000
        entry("varchar", STRING), //varchar(max) is string with length up to 8000
        entry("nvarchar", STRING), //nvarchar(max) is string with length up to 4000
        entry("nchar", STRING), //nchar(max) is string with length up to 4000
        entry("text", STRING_UNBOUNDED),
        entry("ntext", STRING_UNBOUNDED), // Added conversion for ntext (deprecated sql server type)
        entry("binary", BLOB),
        entry("varbinary", BLOB),
        entry("image", IMAGE_BLOB),
        entry("varbinary(max)", BLOB),
        entry("varchar(max)", TEXT_BLOB),
        entry("nvarchar(max)", TEXT_BLOB),
        entry("uniqueidentifier", UUID)
    );

    @Override
    public Map<String, JdlFieldEnum> getTypeMap() {
        return mergeOverrides(this.typeMap, properties.getJdlTypeOverrides());
    }

    @Override
    public JdlFieldEnum sqlTypeToJdlType(String sqlType) {
        sqlType = StringUtils.trim(sqlType);
        final Matcher matcher = COLUMN_TYPE_SIZE_REGEX.matcher(sqlType);

        String typeName = null;
        if (matcher.matches()) {
            Integer max = matcher.group(3) == null ? null : Integer.valueOf(matcher.group(3));
            typeName = matcher.group(1).toLowerCase();
            if (ObjectUtils.isNotEmpty(max)) {
                if (max == COLUMN_TYPE_MAX_LENGTH_MAX_VALUE && typeName.equalsIgnoreCase("varbinary")) {
                    typeName = "varbinary(max)".toLowerCase();
                } else if (max == COLUMN_TYPE_MAX_LENGTH_MAX_VALUE && typeName.equalsIgnoreCase("varchar")) {
                    typeName = "varchar(max)".toLowerCase();
                } else if (max == COLUMN_TYPE_MAX_LENGTH_MAX_VALUE && typeName.equalsIgnoreCase("nvarchar")) {
                    typeName = "nvarchar(max)".toLowerCase();
                }
            }
        }
        return Optional.ofNullable(getTypeMap().get(typeName)).orElse(UNSUPPORTED);
    }

    @Override
    public Integer calculateStringMaxLength(SqlColumn column) {
        return SqlUtils.parseSqlSize(column.getType()).orElse(1);
        //        String columnType = SqlUtils.parseSqlType(column.getType());
        //        if ("VARCHAR".equalsIgnoreCase(columnType) && max == COLUMN_TYPE_MAX_VALUE) {
        //            return VARCHAR_MAX_LENGTH;
        //        }
        //        if ("NVARCHAR".equalsIgnoreCase(columnType) && max == COLUMN_TYPE_MAX_VALUE) {
        //            return NVARCHAR_MAX_LENGTH;
        //        }
        //        return SqlJdlTypeService.super.calculateStringMaxLength(column);
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/service/MySqlJdlTypeService.java
================================================
package org.blackdread.sqltojava.service;

import static java.util.Map.entry;
import static org.blackdread.sqltojava.entity.JdlFieldEnum.*;

import java.util.Map;
import org.blackdread.sqltojava.config.ApplicationProperties;
import org.blackdread.sqltojava.entity.JdlFieldEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Service
@Profile({ "mysql", "mariadb" })
public class MySqlJdlTypeService implements SqlJdlTypeService {

    private static final Logger log = LoggerFactory.getLogger(MySqlJdlTypeService.class);

    private final ApplicationProperties properties;

    public MySqlJdlTypeService(ApplicationProperties properties) {
        this.properties = properties;
    }

    private final Map<String, JdlFieldEnum> typeMap = Map.ofEntries(
        entry("varchar", STRING),
        entry("char", STRING),
        entry("text", STRING),
        entry("tinytext", STRING),
        entry("mediumtext", TEXT_BLOB),
        entry("longtext", TEXT_BLOB),
        entry("tinyblob", BLOB),
        entry("blob", BLOB),
        entry("mediumblob", BLOB),
        entry("longblob", BLOB),
        entry("smallint", INTEGER),
        entry("mediumint", INTEGER),
        entry("int", INTEGER),
        entry("bigint", LONG),
        entry("float", FLOAT),
        entry("double", DOUBLE),
        entry("date", LOCAL_DATE),
        entry("enum", ENUM),
        entry("set", ENUM),
        entry("boolean", BOOLEAN),
        entry("tinyint", BOOLEAN),
        entry("bit", BOOLEAN),
        entry("decimal", BIG_DECIMAL),
        entry("datetime", INSTANT),
        entry("timestamp", INSTANT),
        /**
         * Not support by base jhipster but to export database which has this type.
         * See:
         * https://blog.ippon.fr/2017/12/04/la-technologie-spatiale-au-service-de-jhipster/
         * https://github.com/chegola/jhipster-spatial
         * https://stackoverflow.com/questions/50122390/integration-of-postgis-with-jhipster
         **/
        entry("geometry", GEOMETRY_AS_TEXT),
        /**
         * Not support by base jhipster but to export database which has this type.
         */
        entry("json", JSON_AS_TEXT),
        entry("time", TIME_AS_TEXT),
        entry("year", YEAR_AS_TEXT)
    );

    @Override
    public Map<String, JdlFieldEnum> getTypeMap() {
        return mergeOverrides(this.typeMap, properties.getJdlTypeOverrides());
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/service/OracleJdlTypeService.java
================================================
package org.blackdread.sqltojava.service;

import static java.util.Map.entry;
import static org.blackdread.sqltojava.entity.JdlFieldEnum.*;

import java.util.Map;
import org.blackdread.sqltojava.config.ApplicationProperties;
import org.blackdread.sqltojava.entity.JdlFieldEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Service
@Profile("oracle")
public class OracleJdlTypeService implements SqlJdlTypeService {

    private static final Logger log = LoggerFactory.getLogger(OracleJdlTypeService.class);

    private final ApplicationProperties properties;

    public OracleJdlTypeService(ApplicationProperties properties) {
        this.properties = properties;
    }

    private final Map<String, JdlFieldEnum> typeMap = Map.ofEntries(
        entry("VARCHAR2", STRING),
        entry("NUMBER", INTEGER),
        entry("NUMBER(38)", LONG),
        entry("NUMBER(19,5)", BIG_DECIMAL),
        entry("FLOAT", FLOAT),
        entry("BLOB", BLOB),
        entry("TIMESTAMP", INSTANT),
        entry("DATE", LOCAL_DATE),
        entry("CHAR", STRING),
        entry("CLOB", BLOB),
        entry("NCHAR", STRING),
        entry("NVARCHAR2", STRING),
        entry("RAW", UUID)
    );

    @Override
    public Map<String, JdlFieldEnum> getTypeMap() {
        return this.mergeOverrides(this.typeMap, properties.getJdlTypeOverrides());
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/service/PostgresJdlTypeService.java
================================================
package org.blackdread.sqltojava.service;

import static java.util.Map.entry;
import static org.blackdread.sqltojava.entity.JdlFieldEnum.*;

import java.util.Map;
import org.blackdread.sqltojava.config.ApplicationProperties;
import org.blackdread.sqltojava.entity.JdlFieldEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Service
@Profile("postgresql")
public class PostgresJdlTypeService implements SqlJdlTypeService {

    private static final Logger log = LoggerFactory.getLogger(PostgresJdlTypeService.class);

    private final ApplicationProperties properties;

    public PostgresJdlTypeService(ApplicationProperties properties) {
        this.properties = properties;
    }

    private final Map<String, JdlFieldEnum> typeMap = Map.ofEntries(
        entry("boolean", BOOLEAN),
        entry("date", LOCAL_DATE),
        entry("time without time zone", TIME_AS_TEXT),
        entry("time with time zone", TIME_AS_TEXT),
        entry("timestamp without time zone", INSTANT),
        entry("timestamp with time zone", ZONED_DATE_TIME),
        entry("real", FLOAT),
        entry("double precision", DOUBLE),
        entry("smallint", INTEGER),
        entry("integer", INTEGER),
        entry("bigint", LONG),
        entry("money", BIG_DECIMAL),
        entry("numeric", BIG_DECIMAL),
        entry("character", STRING),
        entry("character varying", STRING),
        entry("text", STRING_UNBOUNDED),
        entry("bytea", BLOB),
        entry("json", JSON_AS_TEXT),
        entry("uuid", UUID)
        //Map.entry("interval", null),
        //Map.entry("jsonb", null),
        //Map.entry("jsonpath", null),
        //Map.entry("macaddr", STRING),
        //Map.entry("macaddr8", STRING),
        //Map.entry("xml", STRING)
    );

    @Override
    public Map<String, JdlFieldEnum> getTypeMap() {
        return mergeOverrides(this.typeMap, properties.getJdlTypeOverrides());
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/service/SqlJdlTypeService.java
================================================
package org.blackdread.sqltojava.service;

import static org.blackdread.sqltojava.entity.JdlFieldEnum.UNSUPPORTED;

import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.blackdread.sqltojava.entity.JdlFieldEnum;
import org.blackdread.sqltojava.entity.SqlColumn;
import org.blackdread.sqltojava.util.SqlUtils;

public interface SqlJdlTypeService {
    Map<String, JdlFieldEnum> getTypeMap();

    default JdlFieldEnum sqlTypeToJdlType(final String sqlType) {
        String typeName = SqlUtils.parseSqlType(sqlType);
        JdlFieldEnum jdlType = Optional.ofNullable(getTypeMap().get(typeName)).orElse(UNSUPPORTED);
        //orElseThrow(() -> new IllegalStateException("Unknown type: " + typeName));
        return jdlType;
    }

    default Map<String, JdlFieldEnum> mergeOverrides(
        final Map<String, JdlFieldEnum> defaultTypeMap,
        final Map<String, JdlFieldEnum> overrides
    ) {
        Map<String, JdlFieldEnum> typeMap = new HashMap<>(defaultTypeMap);
        overrides.forEach((k, v) -> typeMap.merge(k, v, (v1, v2) -> v2));
        return ImmutableMap.copyOf(typeMap);
    }

    default Integer calculateStringMaxLength(SqlColumn column) {
        return SqlUtils.parseSqlSize(column.getType()).orElse(255);
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/service/logic/ExportService.java
================================================
package org.blackdread.sqltojava.service.logic;

import static java.util.Map.entry;
import static java.util.Map.ofEntries;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.blackdread.sqltojava.config.ApplicationProperties;
import org.blackdread.sqltojava.config.ExportFileStructureType;
import org.blackdread.sqltojava.entity.JdlEntity;
import org.blackdread.sqltojava.exporter.ExportFileStructureConfig;
import org.blackdread.sqltojava.util.JdlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class ExportService {

    private static final Logger log = LoggerFactory.getLogger(ExportService.class);

    private final ApplicationProperties properties;
    private final ExportFileStructureConfig exportFileStructureConfig;

    private final JdlService jdlService;

    private final MustacheService mustacheService;

    public ExportService(
        final ApplicationProperties properties,
        ExportFileStructureConfig exportFileStructureConfig,
        JdlService jdlService,
        MustacheService mustacheService
    ) {
        this.properties = properties;
        this.exportFileStructureConfig = exportFileStructureConfig;
        this.jdlService = jdlService;
        this.mustacheService = mustacheService;
    }

    /**
     * Exports jdl to string using mustache.java
     * @param entities
     * @return
     */
    public String exportString(final List<JdlEntity> entities) {
        return mustacheService.executeTemplate(
            exportFileStructureConfig.getExportMustacheTemplateFilename(),
            resolveExportStructure(entities)
        );
    }

    public Map<String, Object> resolveExportStructure(final List<JdlEntity> entities) {
        if (ExportFileStructureType.SEPARATED.equals(exportFileStructureConfig.getExportFileStructureType())) {
            return ofEntries(
                entry("entities", entities),
                entry("relations", jdlService.getRelations(entities)),
                entry("options", !properties.isRenderEntitiesOnly() ? JdlUtils.getOptions() : Collections.emptyList())
            );
        } else if (
            ExportFileStructureType.GROUPED_RELATIONS_SEPARATE_VIEWS.equals(exportFileStructureConfig.getExportFileStructureType())
        ) {
            List<JdlEntity> tables = extractTables(entities);
            List<JdlEntity> views = extractViews(entities);

            return ofEntries(
                entry("entities", tables),
                entry("groupedonetoonerelations", jdlService.getGroupOneToOneRelations(tables)),
                entry("groupedmanytoonerelations", jdlService.getGroupManyToOneRelations(tables)),
                entry("manytomanyrelations", jdlService.getManyToManyRelations(tables)),
                entry("views", views),
                entry("viewsrelations", jdlService.getRelations(views)),
                entry("options", !properties.isRenderEntitiesOnly() ? JdlUtils.getOptions() : Collections.emptyList())
            );
        } else if (
            ExportFileStructureType.RELATIONS_BEFORE_VIEWS_SEPARATE_VIEWS.equals(exportFileStructureConfig.getExportFileStructureType())
        ) {
            List<JdlEntity> tables = extractTables(entities);
            List<JdlEntity> views = extractViews(entities);

            return ofEntries(
                entry("entities", tables),
                entry("onetoonerelations", jdlService.getOneToOneRelations(tables)),
                entry("manytoonerelations", jdlService.getManyToOneRelations(tables)),
                entry("manytomanyrelations", jdlService.getManyToManyRelations(tables)),
                entry("views", views),
                entry("viewsrelations", jdlService.getRelations(views)),
                entry("options", !properties.isRenderEntitiesOnly() ? JdlUtils.getOptions() : Collections.emptyList())
            );
        }
        throw new IllegalStateException("Unknown export file structure type");
    }

    private static List<JdlEntity> extractViews(List<JdlEntity> entities) {
        return entities.stream().filter(JdlEntity::isReadOnly).toList();
    }

    private static List<JdlEntity> extractTables(List<JdlEntity> entities) {
        return entities.stream().filter(e -> !e.isReadOnly()).toList();
    }

    /**
     * Exports jdl to file defined with export.path
     * @param entities
     * @return
     */
    public void export(final List<JdlEntity> entities) {
        final String jdl = exportString(entities);
        final Path path = properties.getExport().getPath();

        log.info("Exporting into: {}", path.toAbsolutePath());

        if (Files.isDirectory(path)) {
            log.error("Path is a directory: {}", path.toAbsolutePath());
            throw new IllegalArgumentException("Cannot export into a directory");
        }

        try {
            Files.deleteIfExists(path);
        } catch (IOException e) {
            log.error("An error occurred when deleting export file");
            throw new IllegalStateException(e);
        }

        try (BufferedWriter out = Files.newBufferedWriter(path, StandardOpenOption.CREATE)) {
            out.write(jdl);
            out.flush();
        } catch (IOException e) {
            log.error("Error", e);
            throw new IllegalStateException(e);
        }
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/service/logic/JdlService.java
================================================
package org.blackdread.sqltojava.service.logic;

import static org.blackdread.sqltojava.entity.JdlFieldEnum.*;
import static org.blackdread.sqltojava.util.NamingConventionUtil.*;

import java.util.*;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.blackdread.sqltojava.config.ApplicationProperties;
import org.blackdread.sqltojava.entity.*;
import org.blackdread.sqltojava.entity.impl.JdlEntityImpl;
import org.blackdread.sqltojava.entity.impl.JdlFieldImpl;
import org.blackdread.sqltojava.entity.impl.JdlRelationGroupImpl;
import org.blackdread.sqltojava.entity.impl.JdlRelationImpl;
import org.blackdread.sqltojava.service.SqlJdlTypeService;
import org.blackdread.sqltojava.util.JdlUtils;
import org.blackdread.sqltojava.util.SqlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class JdlService {

    private static final Logger log = LoggerFactory.getLogger(JdlService.class);

    private final SqlService sqlService;

    private final SqlJdlTypeService sqlJdlTypeService;

    private final ApplicationProperties properties;

    public JdlService(final SqlService sqlService, final ApplicationProperties properties, final SqlJdlTypeService sqlJdlTypeService) {
        this.sqlService = sqlService;
        this.sqlJdlTypeService = sqlJdlTypeService;
        this.properties = properties;
    }

    public List<JdlEntity> buildEntities() {
        final List<SqlColumn> sqlColumns = sqlService.buildColumns();
        // todo build entities for columns of native enums so we can later export to JDL the native enum and its values
        return SqlUtils
            .groupColumnsByTable(sqlColumns)
            .entrySet()
            .stream()
            .map(this::buildEntity)
            .filter(Optional::isPresent)
            .map(Optional::get)
            .sorted()
            .collect(Collectors.toList());
    }

    public List<JdlRelation> getRelations(List<JdlEntity> entities) {
        return entities.stream().flatMap(e -> e.getRelations().stream()).collect(Collectors.toList());
    }

    public List<JdlRelation> getOneToOneRelations(List<JdlEntity> entities) {
        return entities
            .stream()
            .flatMap(e -> e.getRelations().stream())
            .filter(f -> RelationType.OneToOne.equals(f.getRelationType()))
            .collect(Collectors.toList());
    }

    public List<JdlRelation> getManyToOneRelations(List<JdlEntity> entities) {
        return entities
            .stream()
            .flatMap(e -> e.getRelations().stream())
            .filter(f -> RelationType.ManyToOne.equals(f.getRelationType()))
            .collect(Collectors.toList());
    }

    public JdlRelationGroupImpl getGroupManyToOneRelations(List<JdlEntity> entities) {
        List<JdlRelation> idRelations = entities
            .stream()
            .flatMap(e -> e.getRelations().stream())
            .filter(f -> RelationType.ManyToOne.equals(f.getRelationType()))
            .collect(Collectors.toList());

        return new JdlRelationGroupImpl(RelationType.ManyToOne, idRelations);
    }

    public JdlRelationGroupImpl getGroupOneToOneRelations(List<JdlEntity> entities) {
        List<JdlRelation> idRelations = entities
            .stream()
            .flatMap(e -> e.getRelations().stream())
            .filter(f -> RelationType.OneToOne.equals(f.getRelationType()))
            .collect(Collectors.toList());

        return new JdlRelationGroupImpl(RelationType.OneToOne, idRelations);
    }

    public List<JdlRelation> getManyToManyRelations(List<JdlEntity> entities) {
        return entities
            .stream()
            .flatMap(e -> e.getRelations().stream())
            .filter(e -> RelationType.ManyToMany.equals(e.getRelationType()))
            .collect(Collectors.toList());
    }

    private boolean nonDefaultPrimaryKeyFields(final JdlField f) {
        return !isDefaultPrimaryKey(f);
    }

    private boolean isDefaultPrimaryKey(JdlField f) {
        return f.isPrimaryKey() && f.getType().equals(LONG) && f.getName().equals("id");
    }

    protected Optional<JdlEntity> buildEntity(final Map.Entry<SqlTable, List<SqlColumn>> entry) {
        final List<JdlField> fields = entry
            .getValue()
            .stream()
            .map(this::buildField)
            .filter(Optional::isPresent)
            .map(Optional::get)
            .filter(this::nonDefaultPrimaryKeyFields)
            .collect(Collectors.toList());

        final List<JdlRelation> existingRelations = new ArrayList<>();

        final List<JdlRelation> relations = entry
            .getValue()
            .stream()
            .filter(SqlColumn::isForeignKey)
            .map((SqlColumn column) -> buildRelation(column, sqlService.getTableOfForeignKey(column), existingRelations))
            .filter(Optional::isPresent)
            .map(Optional::get)
            .sorted()
            .collect(Collectors.toList());

        String tableName = entry.getKey().getName();
        String entityName = getEntityNameFormatted(tableName);
        List<String> reserved = properties.getReservedList();

        if (reserved.contains(entityName.toUpperCase())) {
            String msg =
                "Skipping processing table [" +
                entry.getKey().getName() +
                "] because " +
                " the transformed entity name [" +
                entityName +
                "] matches with one of the keywords " +
                reserved;
            log.error(msg);
            return Optional.empty();
        }

        JdlEntity jdlEntity = new JdlEntityImpl(
            entityName,
            properties.getAddTableNameJdl() ? tableName : null,
            fields,
            entry.getKey().getComment().orElse(null),
            sqlService.isEnumTable(entry.getKey().getName()),
            !entry.getKey().isUpdatable(),
            sqlService.isPureManyToManyTable(entry.getKey().getName()),
            relations
        );
        return Optional.of(jdlEntity);
    }

    private String getEntityNameFormatted(final String name) {
        return JdlUtils.getEntityName(name, properties.getDatabaseObjectPrefix());
    }

    /**
     * @param column Column from which to create field
     * @return The field or empty if field is to be ignored
     */
    protected Optional<JdlField> buildField(final SqlColumn column) {
        final String name;
        JdlFieldEnum jdlType;
        final String enumEntityName;
        final String comment;
        final boolean isNativeEnum = column.isNativeEnum();
        String pattern = null;

        if (sqlService.isEnumTable(column.getTable().getName())) return Optional.empty();

        if (column.isForeignKey()) {
            // check if table referenced is an enum, otherwise, skip
            final SqlTable tableOfForeignKey = sqlService.getTableOfForeignKey(column);
            if (!sqlService.isEnumTable(tableOfForeignKey.getName())) {
                log.info("Skipped field of ({}) as ({}) is not an enum table", column, tableOfForeignKey);
                return Optional.empty();
            }
            jdlType = ENUM;
            name = SqlUtils.changeToCamelCase(SqlUtils.removeIdFromEnd(column.getName()));
            enumEntityName = StringUtils.capitalize(SqlUtils.changeToCamelCase(SqlUtils.removeIdFromEnd(tableOfForeignKey.getName())));
            comment =
                column
                    .getComment()
                    .map(comment1 -> tableOfForeignKey.getComment().map(c -> comment1 + ". " + c).orElse(comment1))
                    .orElse(tableOfForeignKey.getComment().orElse(null));
        } else {
            if (isNativeEnum) {
                jdlType = ENUM;
                name = SqlUtils.changeToCamelCase(toTitleCase(column.getName()).replace(" ", ""));
                // todo name of enumEntityName is not great but never mind
                enumEntityName = StringUtils.capitalize(SqlUtils.changeToCamelCase(SqlUtils.removeIdFromEnd(column.getName())));
            } else {
                jdlType = sqlJdlTypeService.sqlTypeToJdlType(column.getType());
                name = SqlUtils.changeToCamelCase(replaceSlavenChars(toTitleCase(column.getName())));
                log.info("column name change sql to jdl format: {}, {}", column.getName(), name);
                enumEntityName = null;
            }
            if (jdlType == UNSUPPORTED) {
                comment = String.join(column.getComment().orElse(""), " ", column.getType());
            } else {
                comment = column.getComment().orElse(null);
            }
            //    comment = (jdlType=UNSUPPORTED) column.getComment().orElse(null);
        }

        final Integer min;
        final Integer max;
        switch (jdlType) {
            // We always define max for string
            case STRING -> {
                min = null;
                max = sqlJdlTypeService.calculateStringMaxLength(column);
            }
            case TIME_AS_TEXT -> {
                pattern = "^(([0-1]\\d)|(2[0-3])):([0-5]\\d):([0-5]\\d)$";
                jdlType = STRING;
                max = 8;
                min = 8;
            }
            case YEAR_AS_TEXT -> {
                pattern = "^-?(\\d+)$";
                jdlType = STRING;
                max = null;
                min = null;
            }
            case GEOMETRY_AS_TEXT, JSON_AS_TEXT, STRING_UNBOUNDED -> {
                jdlType = STRING;
                max = null;
                min = null;
            }
            default -> {
                min = null;
                max = null;
            }
        }

        // Min and pattern are not set as we cannot guess it (unless we define it in comments -> parse)

        return Optional.of(
            new JdlFieldImpl(
                jdlType,
                name,
                !column.isNullable(),
                comment,
                min,
                max,
                pattern,
                enumEntityName,
                isNativeEnum,
                column.isUnique(),
                column.isPrimaryKey()
            )
        );
    }

    /**
     * @param column            Column from which to create relation, owner side of the relation
     * @param inverseSideTable  The table referenced by the column of the owner side
     * @param existingRelations Cache for checking already registered relations, needed to avoid name duplication
     * @return The relation or empty if relation is to be ignored
     */
    protected Optional<JdlRelation> buildRelation(
        final SqlColumn column,
        final SqlTable inverseSideTable,
        final List<JdlRelation> existingRelations
    ) {
        if (!column.isForeignKey()) throw new IllegalArgumentException("Cannot create a relation from a non foreign key");

        final SqlTable ownerSideTable = column.getTable();
        final String tableName = ownerSideTable.getName();
        final String columnName = column.getName();

        final boolean isNullable = column.isNullable();

        final boolean isUnique = column.isUnique();

        if (sqlService.isEnumTable(inverseSideTable.getName())) {
            log.info("Skipped relation of ({}) as ({}) is an enum table", column, inverseSideTable);
            return Optional.empty();
        }

        final boolean isPureManyToManyTable = sqlService.isPureManyToManyTable(tableName);

        // it allows to have a clearer idea when reading the generated file
        final String extraRelationComment = column.getTable().getComment().orElse(null);

        final RelationType relationType;
        if (isPureManyToManyTable) {
            relationType = RelationType.ManyToMany;
        } else {
            if (isUnique) {
                relationType = RelationType.OneToOne;
            } else {
                relationType = RelationType.ManyToOne;
            }
        }

        // TeamMember{user(login) required} to User
        final String inverseSideEntityName = getEntityNameFormatted(inverseSideTable.getName());

        // We put always bidirectional but we have no way to generate good inverse name so we put the owner side name
        final String ownerEntityName = getEntityNameFormatted(tableName);
        final String inverseSideRelationName = buildInverseSideRelationName(
            inverseSideEntityName,
            ownerEntityName,
            columnName,
            existingRelations
        );
        boolean required = !isNullable;
        if (required) {
            if (ownerEntityName.equals(inverseSideEntityName)) {
                String msg =
                    "Detected a Self Reference in the table " +
                    tableName +
                    ". JHipster JDL currently does not support Reflexive relationships. " +
                    "Set [nullable] as [true] for column [" +
                    columnName +
                    "] to fix errors when using the JDL with JHipster";
                log.warn(msg);
                required = false;
            }
        }

        final JdlRelationImpl relation = new JdlRelationImpl(
            relationType,
            properties.isAssumeBidirectional(),
            required,
            false,
            ownerEntityName,
            inverseSideEntityName,
            SqlUtils.changeToCamelCase(SqlUtils.removeIdFromEnd(columnName)),
            sqlService.getDisplayFieldOfTable(inverseSideTable),
            column.getComment().orElse(null),
            null,
            inverseSideRelationName,
            sqlService.getDisplayFieldOfTable(ownerSideTable),
            extraRelationComment
        );

        existingRelations.add(relation);

        return Optional.of(relation);
    }

    /**
     * @param inverseSideEntityName The table name referenced by the column of the owner side
     * @param ownerEntityName       Table name of column from which to create relation, owner side of the relation
     * @param columnName            Column name from which to create relation, owner side of the relation
     * @param existingRelations     Cache for checking already registered relations, needed to avoid name duplication
     * @return Modified name of ownerEntity or full name consisting of ownerEntity and columnName
     */
    private String buildInverseSideRelationName(
        String inverseSideEntityName,
        String ownerEntityName,
        String columnName,
        List<JdlRelation> existingRelations
    ) {
        String possibleRelationName = JdlUtils.decapitalize(ownerEntityName);
        // Looking for a full match of names within 1 entity
        final boolean relationAlreadyExist = existingRelations
            .stream()
            .anyMatch(jdlRelation ->
                ownerEntityName.equals(jdlRelation.getOwnerEntityName()) &&
                possibleRelationName.equals(jdlRelation.getInverseSideRelationName().orElse(null)) &&
                inverseSideEntityName.equals(jdlRelation.getInverseSideEntityName())
            );

        if (relationAlreadyExist) {
            //As stated earlier, we have no way to generate a good reverse name, so we put the owner's side name.
            //So we simply combine the relationship name and the column name
            return possibleRelationName + "Of" + StringUtils.capitalize(SqlUtils.changeToCamelCase(SqlUtils.removeIdFromEnd(columnName)));
        } else {
            return possibleRelationName;
        }
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/service/logic/MustacheService.java
================================================
package org.blackdread.sqltojava.service.logic;

import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import com.github.mustachejava.MustacheFactory;
import com.github.mustachejava.reflect.ReflectionObjectHandler;
import com.github.mustachejava.util.DecoratedCollection;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Map;
import org.blackdread.sqltojava.config.ApplicationProperties;
import org.blackdread.sqltojava.entity.impl.JdlEntityImpl;
import org.blackdread.sqltojava.entity.impl.JdlFieldImpl;
import org.blackdread.sqltojava.entity.impl.JdlRelationGroupImpl;
import org.blackdread.sqltojava.entity.impl.JdlRelationImpl;
import org.blackdread.sqltojava.view.mapper.JdlViewMapperImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class MustacheService {

    private static final Logger log = LoggerFactory.getLogger(MustacheService.class);
    private static final String MUSTACHE_EXTENSION = ".mustache";
    private final MustacheFactory mf;

    private final ApplicationProperties properties;

    public MustacheService(ApplicationProperties properties) {
        this.mf = getMustacheFactory();
        this.properties = properties;
    }

    /**
     * Load templates from resources/mustache.  The assumed extension is .mustache so only the file name needs to be specified.
     * @param template
     * @param context
     * @return
     */
    public String executeTemplate(String template, Map<String, Object> context) {
        Mustache m = mf.compile(template + MUSTACHE_EXTENSION);
        try {
            StringWriter writer = new StringWriter();
            m.execute(writer, context).flush();
            return replaceMultpleBlankLinesWithOne(writer.toString());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private String replaceMultpleBlankLinesWithOne(String s) {
        return s.replaceAll("([ \\tw]*\\n){3,}", "\\\n\\\n").replaceAll("\\n\\n$", "\\\n");
    }

    /**
     * Create a MustacheFactory with a MapstructBasedObjectHandler
     * @return MustacheFactory
     */
    private MustacheFactory getMustacheFactory() {
        DefaultMustacheFactory mf = new DefaultMustacheFactory("mustache");
        mf.setObjectHandler(new MapstructBasedObjectHandler());
        return mf;
    }

    /**
     * Use Mapstruct to map the JDL model to view DTOs for rendering with mustache.java
     */
    private class MapstructBasedObjectHandler extends ReflectionObjectHandler {

        private static JdlViewMapperImpl mapper = new JdlViewMapperImpl();

        @Override
        public Object coerce(Object o) {
            if (o instanceof JdlRelationGroupImpl) return mapper.relationToView((JdlRelationGroupImpl) o);
            if (o instanceof JdlEntityImpl) return mapper.entityToView((JdlEntityImpl) o, properties.getUndefinedTypeHandling());
            if (o instanceof JdlFieldImpl) return mapper.fieldToView((JdlFieldImpl) o);
            if (o instanceof JdlRelationImpl) return mapper.relationToView((JdlRelationImpl) o);
            if (o instanceof Collection) return new DecoratedCollection((Collection) o);
            return super.coerce(o);
        }
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/service/logic/SqlService.java
================================================
package org.blackdread.sqltojava.service.logic;

import com.google.common.collect.Maps;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.blackdread.sqltojava.config.ApplicationProperties;
import org.blackdread.sqltojava.config.DatabaseObjectTypesConfigEnum;
import org.blackdread.sqltojava.entity.SqlColumn;
import org.blackdread.sqltojava.entity.SqlTable;
import org.blackdread.sqltojava.entity.impl.SqlColumnImpl;
import org.blackdread.sqltojava.entity.impl.SqlTableImpl;
import org.blackdread.sqltojava.pojo.ColumnInformation;
import org.blackdread.sqltojava.pojo.TableInformation;
import org.blackdread.sqltojava.pojo.TableRelationInformation;
import org.blackdread.sqltojava.service.InformationSchemaService;
import org.blackdread.sqltojava.util.SqlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
public class SqlService {

    private static final Logger log = LoggerFactory.getLogger(SqlService.class);

    private final ApplicationProperties applicationProperties;

    private final InformationSchemaService informationSchemaService;

    @Autowired
    public SqlService(final ApplicationProperties applicationProperties, final InformationSchemaService informationSchemaService) {
        this.applicationProperties = applicationProperties;
        this.informationSchemaService = informationSchemaService;
    }

    // @Cacheable does not work when in same class so we loose a bit in efficiency but repo is cached as well so...

    @Cacheable("SqlService.buildTables")
    public List<SqlTable> buildTables() {
        log.debug("buildTables called");
        final List<String> ignoredTableNames = applicationProperties.getIgnoredTableNames();
        return informationSchemaService
            .getAllTableInformation()
            .stream()
            .filter(table -> includeType(table, applicationProperties.getDatabaseObjectTypesConfig()))
            .filter(table -> !doesTableEndWithDetailKeyword(table))
            .filter(table -> !isTableIgnored(ignoredTableNames, table))
            .map(table -> new SqlTableImpl(table.getName(), table.getComment().orElse(null), table.getType(), table.isUpdateable()))
            .collect(Collectors.toList());
    }

    private boolean includeType(TableInformation table, DatabaseObjectTypesConfigEnum databaseObjectTypesConfig) {
        return switch (databaseObjectTypesConfig) {
            case ALL -> true;
            case TABLES -> table.getType().equals("BASE TABLE");
            case VIEWS -> table.getType().equals("VIEW");
        };
    }

    private boolean doesTableEndWithDetailKeyword(TableInformation table) {
        String tablename = table.getName();
        boolean result = tablename.toLowerCase().endsWith("_detail");
        if (result) {
            String msg = String.format(
                "Skipped processing table [%s] which ends with the JDL keyword [Detail]. " +
                "Please alter the table name to something else (for e.g., adding [details] as the suffix)",
                tablename
            );
            log.error(msg);
        }
        return result;
    }

    @Cacheable("SqlService.buildColumns")
    public List<SqlColumn> buildColumns() {
        log.debug("buildColumns called");
        return buildTables()
            .stream()
            .map(table -> Maps.immutableEntry(table, informationSchemaService.getFullColumnInformationOfTable(table.getName())))
            .map(entry ->
                entry
                    .getValue()
                    .stream()
                    .map(columnInformation -> {
                        final String columnType = columnInformation.getType();

                        // hard coded for now, we can later extract in some service, etc.
                        final boolean isNativeEnum = columnType.startsWith("enum") || columnType.startsWith("set");

                        return new SqlColumnImpl(
                            entry.getKey(),
                            columnInformation.getName(),
                            columnType,
                            columnInformation.isPrimary(),
                            isForeignKey(entry.getKey().getName(), columnInformation.getName()),
                            columnInformation.isNullable(),
                            columnInformation.isUnique(),
                            isNativeEnum,
                            columnInformation.getDefaultValue().orElse(null),
                            columnInformation.getComment()
                        );
                    })
                    .collect(Collectors.toList())
            )
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
    }

    @Cacheable("SqlService.getTableOfForeignKey")
    public SqlTable getTableOfForeignKey(final SqlColumn column) {
        log.debug("getTableOfForeignKey called: ({}) ({})", column.getTable().getName(), column.getName());
        return informationSchemaService
            .getAllTableRelationInformation()
            .stream()
            .filter(e -> e.getTableName().equals(column.getTable().getName()))
            .filter(e -> e.getColumnName().equals(column.getName()))
            .findFirst()
            .map(TableRelationInformation::getReferencedTableName)
            .map(tableName -> buildTables().stream().filter(e -> e.getName().equals(tableName)).findFirst())
            .map(sqlTable -> sqlTable.orElseThrow(() -> new IllegalStateException("Table not found or is ignored")))
            .orElseThrow(() -> new IllegalArgumentException("Column is not a foreign key"));
    }

    /**
     * Get the display field for a table.
     * The display field to chosen as a column with a unique constraint the with a unique constraint that has the lowest original position.
     * @param table
     * @return
     */
    @Cacheable("SqlService.getDisplayFieldOfTable")
    public String getDisplayFieldOfTable(final SqlTable table) {
        String tableName = table.getName();
        log.debug("getDisplayFieldOfTable called: ({})", tableName);
        return informationSchemaService
            .getFullColumnInformationOfTable(table.getName())
            .stream()
            .sorted(Comparator.comparingInt(ColumnInformation::getOrdinalPosition))
            .filter(ColumnInformation::isUnique)
            .filter(c -> !isForeignKey(tableName, c.getName()))
            .findFirst()
            .map(ColumnInformation::getName)
            .orElse(null);
    }

    @Cacheable("SqlService.isEnumTable")
    public boolean isEnumTable(final String tableName) {
        final List<ColumnInformation> table = informationSchemaService.getFullColumnInformationOfTable(tableName);

        if (table.size() != 2) return false;

        for (final ColumnInformation column : table) {
            // Our design contract define that id and code/name is an enum table so logic is put here
            if (
                !column.getName().equalsIgnoreCase("id") &&
                (!column.getName().equalsIgnoreCase("code") && !column.getName().equalsIgnoreCase("name"))
            ) return false;
        }

        return true;
    }

    /**
     * Used to get enums values for an enum materialized with a table
     *
     * @param tableName Table name
     * @return enum values
     * @deprecated not implemented yet
     */
    @Cacheable("SqlService.getEnumValuesForTable")
    public List<String> getEnumValues(final String tableName) {
        throw new IllegalStateException("todo");
    }

    /**
     * Used to get enums values for a native enum
     *
     * @param tableName  Table name
     * @param columnName column name
     * @return enum values
     * @deprecated not implemented yet
     */
    @Cacheable("SqlService.getEnumValuesForColumn")
    public List<String> getEnumValues(final String tableName, final String columnName) {
        throw new IllegalStateException("todo");
    }

    /**
     * Check if the column name passed from the table name specified is referencing an enum table
     *
     * @param tableName  Table containing the FK column
     * @param columnName FK column that reference the enum table
     * @return True if this column name is referencing an enum table
     */
    @Cacheable("SqlService.isForeignKeyFromAnEnumTable")
    public boolean isForeignKeyFromAnEnumTable(final String tableName, final String columnName) {
        if (!isForeignKey(tableName, columnName)) return false;
        return isEnumTable(SqlUtils.removeIdFromEnd(columnName));
    }

    /**
     * @param tableName  Table to check
     * @param columnName Column to check
     * @return True if column is a foreign key
     */
    @Cacheable("SqlService.isForeignKey")
    public boolean isForeignKey(final String tableName, final String columnName) {
        return informationSchemaService
            .getAllTableRelationInformation()
            .stream()
            .filter(e -> e.getTableName().equals(tableName))
            .anyMatch(e -> e.getColumnName().equals(columnName));
    }

    /**
     * A pure many to many table is a table with 2 columns and both are foreign keys.
     * <p>Other MtM tables add other columns and treated as real entities with MtO relations</p>
     *
     * @param tableName Table to check
     * @return True if this table is a pure many to many table (2 columns, 2 FK)
     */
    @Cacheable("SqlService.isPureManyToManyTable")
    public boolean isPureManyToManyTable(final String tableName) {
        final List<ColumnInformation> table = informationSchemaService.getFullColumnInformationOfTable(tableName);

        if (table.size() != 2) return false;

        for (final ColumnInformation column : table) {
            if (!isForeignKey(tableName, column.getName())) return false;
        }

        return true;
    }

    private boolean isTableIgnored(final List<String> ignoredTableNames, final TableInformation table) {
        return ignoredTableNames.contains(table.getName());
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/util/AppUtil.java
================================================
package org.blackdread.sqltojava.util;

import org.blackdread.sqltojava.listener.SetDatabaseProfileApplicationEventListener;
import org.springframework.boot.SpringApplication;

public final class AppUtil {

    /**
     * Utility method to configure application the same in both tests and production since the
     * main method is not called when the tests run and the database profile needs to be set in
     * ApplicationEnvironmentPreparedEvent which runs before the context is loaded.
     * @param app
     * @return
     */
    public static SpringApplication setup(SpringApplication app) {
        app.addListeners(new SetDatabaseProfileApplicationEventListener());
        return app;
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/util/JdbcUtil.java
================================================
package org.blackdread.sqltojava.util;

public final class JdbcUtil {

    /**
     * This method assumes the jdbc url starts with "jdbc:database_type:"
     * @param jdbcUrl
     * @return
     */
    public static String getDatabaseTypeFromJdbcUrl(String jdbcUrl) {
        String[] parts = jdbcUrl.split(":");
        assert parts[0].equals("jdbc");
        return parts[1];
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/util/JdlUtils.java
================================================
package org.blackdread.sqltojava.util;

import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.NotNull;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class JdlUtils {

    private static final Logger log = LoggerFactory.getLogger(JdlUtils.class);

    private JdlUtils() {}

    @NotNull
    public static String paginationAll() {
        return "paginate * with pagination";
    }

    @NotNull
    public static String serviceClassAll() {
        return "service * with serviceClass";
    }

    @NotNull
    public static String mapStructAll() {
        return "dto * with mapstruct";
    }

    @NotNull
    public static String angularSuffixAll(final String suffix) {
        return "angularSuffix * with " + suffix;
    }

    @NotNull
    public static String filterAll() {
        return "filter *";
    }

    public static String getEntityName(String name, List<String> prefixes) {
        String entityName = prefixes
            .stream()
            .filter(prefix -> name.startsWith(prefix))
            .findFirst()
            .map(s -> name.substring(s.length()))
            .orElse(name);
        return StringUtils.capitalize(SqlUtils.changeToCamelCase(entityName));
    }

    public static String decapitalize(String string) {
        char c[] = string.toCharArray();
        c[0] = Character.toLowerCase(c[0]);
        return new String(c);
    }

    public static List<String> getOptions() {
        List<String> options = new ArrayList<>();
        options.add(JdlUtils.serviceClassAll());
        options.add(JdlUtils.paginationAll());
        options.add(JdlUtils.mapStructAll());
        options.add(JdlUtils.filterAll());
        return options;
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/util/NamingConventionUtil.java
================================================
package org.blackdread.sqltojava.util;

import java.util.Arrays;
import java.util.stream.Collectors;

public final class NamingConventionUtil {

    public static String replaceSlavenChars(String columnName) {
        return columnName
            .replace(" ", "")
            .replace("š", "s")
            .replace("č", "c")
            .replace("ž", "z")
            .replace("ć", "c")
            .replace("đ", "d")
            .replace(" ", "")
            .replace("Š", "S")
            .replace("Č", "C")
            .replace("Ž", "Z")
            .replace("Ć", "C")
            .replace("Đ", "D");
    }

    public static String toTitleCase(String sentence) {
        if (sentence == null || sentence.isEmpty()) {
            return sentence;
        }
        if (!sentence.contains(" ")) {
            return sentence;
        }
        return Arrays
            .stream(sentence.split(" "))
            .map(word -> Character.toUpperCase(word.charAt(0)) + word.substring(1).toLowerCase())
            .collect(Collectors.joining(" "));
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/util/ResourceUtil.java
================================================
package org.blackdread.sqltojava.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;

public final class ResourceUtil {

    private static final Logger log = LoggerFactory.getLogger(ResourceUtil.class);

    public static String readString(Resource resource) {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))) {
            return reader.lines().collect(Collectors.joining(System.lineSeparator()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static String readString(String path) {
        try {
            InputStream is = ResourceUtil.class.getClassLoader().getResourceAsStream(path);
            String text = new String(is.readAllBytes(), StandardCharsets.UTF_8);
            return text;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static String getFirstExistingResourcePath(String fileName, String... paths) {
        for (String path : paths) {
            if (ResourceUtil.class.getResource(path) != null) {
                log.info(String.format("%s found at %s", fileName, path));
                return path;
            } else {
                log.info(String.format("%s not found at %s", fileName, path));
            }
        }
        throw new RuntimeException(String.format("Could not find %s", fileName));
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/util/SqlUtils.java
================================================
package org.blackdread.sqltojava.util;

import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static java.util.Optional.empty;

import com.google.common.base.CaseFormat;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import org.blackdread.sqltojava.entity.SqlColumn;
import org.blackdread.sqltojava.entity.SqlTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class SqlUtils {

    private static final Logger log = LoggerFactory.getLogger(SqlUtils.class);

    public static final Pattern COLUMN_TYPE_SIZE_REGEX = Pattern.compile("(^[a-z0-9\\s]+)(\\((\\-?[0-9]+)\\))?$", Pattern.CASE_INSENSITIVE);

    private SqlUtils() {}

    /**
     * @param value A string that might ends with "_id" or "Id"
     * @return Value without any ID suffix
     */
    public static String removeIdFromEnd(final String value) {
        return value.toLowerCase().endsWith("_id")
            ? value.substring(0, value.length() - 3)
            : value.endsWith("Id") ? value.substring(0, value.length() - 2) : value;
    }

    public static String changeToCamelCase(final String value) {
        if (value.contains("_")) {
            return CaseFormat.LOWER_UNDERSCORE.to(LOWER_CAMEL, value);
        } else if (value.equals(value.toUpperCase())) {
            // If the string is in all uppercase, convert it to lowercase
            return value.toLowerCase();
        } else {
            // If the string contains uppercase letters in the middle, split the string into words
            // based on the uppercase letters, then join the words with the first word in lowercase
            // and the rest of the words in their original case
            String[] words = value.split("(?=[A-Z])");
            String res = Stream.of(words).map(word -> word.equals(words[0]) ? word.toLowerCase() : word).collect(Collectors.joining());
            return changeIdToLowerCase(res).replace("ID", "Id");
        }
    }

    public static String changeIdToLowerCase(final String value) {
        if (value == null || value.isEmpty()) {
            return value;
        }
        if (value.startsWith("iD") && Character.isUpperCase(value.charAt(2))) {
            return "id" + value.substring(2);
        }
        return value;
    }

    public static Map<SqlTable, List<SqlColumn>> groupColumnsByTable(final List<SqlColumn> sqlColumns) {
        return sqlColumns.stream().collect(Collectors.groupingBy(SqlColumn::getTable, Collectors.toList()));
    }

    public static Optional<Integer> parseSqlSize(String value) {
        value = StringUtils.trim(value);
        final Matcher matcher = COLUMN_TYPE_SIZE_REGEX.matcher(value);

        if ("character varying".equalsIgnoreCase(value)) {
            // quick fix due to new regex used -> "matcher.matches()" returns true
            return empty();
        }

        if (matcher.matches()) {
            return Optional.of(Integer.valueOf(matcher.group(3)));
        }
        log.warn("Did not find sql size from: {}", value);
        return empty();
    }

    public static String parseSqlType(String value) {
        // todo: Oracle Bigint, BigDecimal
        if (value.equals("NUMBER(38)") || value.equals("NUMBER(19,5)")) {
            return value;
        }
        return value.split("\\(")[0];
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/view/JdlCommentView.java
================================================
package org.blackdread.sqltojava.view;

import java.util.Optional;

/**
 * Methods for comments in the view
 */
public interface JdlCommentView {
    Optional<String> getComment();

    default String getImplComment(String comment) {
        return (comment != null) ? "// " + comment : null;
    }

    default String getDocComment(String comment) {
        return (comment != null) ? "/** " + comment + " */" : null;
    }

    default String getDocComment() {
        return getDocComment(getComment().orElse(null));
    }

    default String getImplComment() {
        return getImplComment(getComment().orElse(null));
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/view/JdlEntityView.java
================================================
package org.blackdread.sqltojava.view;

import static org.slf4j.LoggerFactory.getLogger;

import java.util.List;
import java.util.stream.Collectors;
import org.blackdread.sqltojava.config.UndefinedJdlTypeHandlingEnum;
import org.blackdread.sqltojava.entity.JdlEntity;
import org.blackdread.sqltojava.entity.JdlField;
import org.slf4j.Logger;

/**
 * Methods for JDL entities in the view
 */
public interface JdlEntityView extends JdlEntity, JdlCommentView {
    UndefinedJdlTypeHandlingEnum getUndefinedJdlTypeHandling();

    default String getType() {
        return (isEnumEntity()) ? "enum" : "entity";
    }

    default String tableName() {
        return (getTableName() != null) ? String.format("(%s)", getTableName()) : null;
    }

    default List<JdlField> filteredFields() {
        return getFields().stream().filter(f -> filterUnsupported(getUndefinedJdlTypeHandling(), f)).collect(Collectors.toList());
    }

    /**
     * Filters fields and throws error based on UndefinedJdlTypeHandling
     *
     * @return
     */
    default boolean filterUnsupported(UndefinedJdlTypeHandlingEnum undefinedJdlTypeHandling, JdlField field) {
        switch (field.getType()) {
            case UNSUPPORTED -> {
                switch (undefinedJdlTypeHandling) {
                    case UNSUPPORTED -> {
                        return true;
                    }
                    case SKIP -> {
                        log().warn("Skipping unsupportd field {}", field);
                        return false;
                    }
                    case ERROR -> throw new RuntimeException(String.format("Unsupported jdl type %s", field));
                    //                    case ERROR -> {
                    //                        log().error("Unsupported jdl type {}", field);
                    //                        return false;
                    //                    }
                    default -> throw new RuntimeException(
                        String.format("Unhandled UndefinedJdlTypeHandlingEnum: %s", undefinedJdlTypeHandling)
                    );
                }
            }
            default -> {
                return true;
            }
        }
    }

    private static Logger log() {
        final class LogHolder {

            private static final Logger LOGGER = getLogger(JdlEntityView.class);
        }
        return LogHolder.LOGGER;
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/view/JdlFieldView.java
================================================
package org.blackdread.sqltojava.view;

import com.google.common.base.Joiner;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.NotNull;
import org.blackdread.sqltojava.entity.JdlField;
import org.blackdread.sqltojava.entity.JdlFieldEnum;

/**
 * Methods for JDL fields in the view
 */
public interface JdlFieldView extends JdlField, JdlCommentView {
    //TODO This validation should be handled in JdlService
    default String getTypeName() {
        JdlFieldEnum type = getType();
        return switch (type) {
            case ENUM -> getEnumEntityName()
                .orElseThrow(() -> new IllegalStateException("An enum field must have its enum entity name set"));
            default -> (("UUID".equals(type.name())) ? type.name() : type.toCamelUpper());
        };
    }

    default String constraints() {
        List<String> constraints = new ArrayList<>();
        if (renderRequired()) constraints.add(requiredConstraint());
        if (isUnique()) constraints.add(uniqueConstraint());
        getMin().ifPresent(min -> constraints.add(minConstraint(min)));
        getMax().ifPresent(max -> constraints.add(maxConstraint(max)));
        getPattern().ifPresent(pattern -> constraints.add(patternConstraint(pattern)));
        return (!constraints.isEmpty()) ? " ".concat(Joiner.on(" ").join(constraints)) : null;
    }

    // TODO do not write required when field is primary key
    default boolean renderRequired() {
        // if (!isPrimaryKey() && isRequired() && ) constraints.add(JdlUtils.validationRequired());
        return isRequired() && !(getName().equals("id") && getType().equals(JdlFieldEnum.UUID));
    }

    @NotNull
    default String requiredConstraint() {
        return "required";
    }

    @NotNull
    default String uniqueConstraint() {
        return "unique";
    }

    default String minConstraint(int min) {
        return switch (getType()) {
            case STRING -> validationMinLength(min);
            default -> validationMin(min);
        };
    }

    default String maxConstraint(int max) {
        return switch (getType()) {
            case STRING -> validationMaxLength(max);
            default -> validationMax(max);
        };
    }

    //TODO This validation should be handled in JdlService
    default String patternConstraint(String pattern) {
        return switch (getType()) {
            case STRING -> validationPattern(pattern);
            default -> throw new RuntimeException("Only String can have a pattern");
        };
    }

    @NotNull
    default String validationMax(final int max) {
        return "max(" + max + ")";
    }

    @NotNull
    default String validationMin(final int min) {
        return "min(" + min + ")";
    }

    default String validationMaxLength(final int max) {
        return "maxlength(" + max + ")";
    }

    @NotNull
    default String validationMinLength(final int min) {
        return "minlength(" + min + ")";
    }

    @NotNull
    default String validationPattern(final String pattern) {
        return "pattern(/" + pattern + "/)";
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/view/JdlRelationGroupView.java
================================================
package org.blackdread.sqltojava.view;

import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;

@Immutable
@ThreadSafe
public interface JdlRelationGroupView {}


================================================
FILE: src/main/java/org/blackdread/sqltojava/view/JdlRelationView.java
================================================
package org.blackdread.sqltojava.view;

import java.util.Optional;
import org.blackdread.sqltojava.entity.JdlRelation;
import org.blackdread.sqltojava.entity.RelationType;

/**
 * Methods for JDL relations in the view
 */
public interface JdlRelationView extends JdlRelation, JdlCommentView {
    default String getType() {
        return getRelationType().toJdl();
    }

    default boolean isPureManyToMany() {
        return getRelationType() == RelationType.ManyToMany;
    }

    default String getOwnerDocComment() {
        return getDocComment(getOwnerComment().orElse(null));
    }

    default boolean hasComments() {
        return getOwnerComment().isPresent() || getInverseSideComment().isPresent();
    }

    default String getInverseDocComment() {
        return getDocComment(getInverseSideComment().orElse(null));
    }

    default String getOwnerConfig() {
        return "{" + getOwnerRelationName() + getRelationConfig(getOwnerDisplayField(), isOwnerRequired()) + "}";
    }

    default String getInverseConfig() {
        if (isBidirectional()) {
            return (
                "{" +
                getInverseSideRelationName().orElse("") +
                getRelationConfig(getInverseSideDisplayField(), isInverseSideRequired()) +
                "}"
            );
        } else {
            return null;
        }
    }

    default String getDisplayField(Optional<String> relation) {
        return relation.map(displayName -> "(" + displayName + ")").orElse("");
    }

    default String getRelationConfig(Optional<String> relation, boolean required) {
        return getDisplayField(relation) + ((required) ? " required" : "");
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/view/impl/JdlEntityViewImpl.java
================================================
package org.blackdread.sqltojava.view.impl;

import java.util.List;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
import org.blackdread.sqltojava.config.UndefinedJdlTypeHandlingEnum;
import org.blackdread.sqltojava.entity.JdlField;
import org.blackdread.sqltojava.entity.JdlRelation;
import org.blackdread.sqltojava.entity.impl.JdlEntityImpl;
import org.blackdread.sqltojava.view.JdlEntityView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Immutable
@ThreadSafe
public class JdlEntityViewImpl extends JdlEntityImpl implements JdlEntityView {

    private static final Logger log = LoggerFactory.getLogger(JdlEntityViewImpl.class);

    private final UndefinedJdlTypeHandlingEnum undefinedJdlTypeHandling;

    /**
     * Constructory based on super
     * @param name
     * @param tableName
     * @param fields
     * @param comment
     * @param enumEntity
     * @param readOnly
     * @param pureManyToMany
     * @param relations
     */
    public JdlEntityViewImpl(
        String name,
        String tableName,
        List<JdlField> fields,
        @Nullable String comment,
        boolean enumEntity,
        boolean readOnly,
        boolean pureManyToMany,
        List<JdlRelation> relations,
        UndefinedJdlTypeHandlingEnum undefinedJdlTypeHandling
    ) {
        super(name, tableName, fields, comment, enumEntity, readOnly, pureManyToMany, relations);
        this.undefinedJdlTypeHandling = undefinedJdlTypeHandling;
    }

    @Override
    public UndefinedJdlTypeHandlingEnum getUndefinedJdlTypeHandling() {
        return undefinedJdlTypeHandling;
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/view/impl/JdlFieldViewImpl.java
================================================
package org.blackdread.sqltojava.view.impl;

import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
import org.blackdread.sqltojava.entity.JdlFieldEnum;
import org.blackdread.sqltojava.entity.impl.JdlFieldImpl;
import org.blackdread.sqltojava.service.logic.JdlService;
import org.blackdread.sqltojava.view.JdlFieldView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Immutable
@ThreadSafe
public class JdlFieldViewImpl extends JdlFieldImpl implements JdlFieldView {

    private static final Logger log = LoggerFactory.getLogger(JdlService.class);

    /**
     * Constructory based on super
     * @param type
     * @param name
     * @param required
     * @param comment
     * @param min
     * @param max
     * @param pattern
     * @param enumEntityName
     * @param nativeEnum
     * @param unique
     * @param primaryKey
     */
    public JdlFieldViewImpl(
        JdlFieldEnum type,
        String name,
        boolean required,
        @Nullable String comment,
        @Nullable Integer min,
        @Nullable Integer max,
        @Nullable String pattern,
        @Nullable String enumEntityName,
        Boolean nativeEnum,
        Boolean unique,
        Boolean primaryKey
    ) {
        super(type, name, required, comment, min, max, pattern, enumEntityName, nativeEnum, unique, primaryKey);
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/view/impl/JdlRelationGroupViewImpl.java
================================================
package org.blackdread.sqltojava.view.impl;

import java.util.List;
import java.util.Optional;
import org.blackdread.sqltojava.entity.JdlRelation;
import org.blackdread.sqltojava.entity.RelationType;
import org.blackdread.sqltojava.entity.impl.JdlRelationGroupImpl;

public class JdlRelationGroupViewImpl extends JdlRelationGroupImpl {

    public JdlRelationGroupViewImpl(RelationType relationType, List<JdlRelation> relations) {
        super(relationType, relations);
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/view/impl/JdlRelationViewImpl.java
================================================
package org.blackdread.sqltojava.view.impl;

import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
import org.blackdread.sqltojava.entity.RelationType;
import org.blackdread.sqltojava.entity.impl.JdlRelationImpl;
import org.blackdread.sqltojava.view.JdlRelationView;

@Immutable
@ThreadSafe
public class JdlRelationViewImpl extends JdlRelationImpl implements JdlRelationView {

    /**
     * Constructory based on super
     * @param relationType
     * @param bidirectional
     * @param ownerRequired
     * @param inverseSideRequired
     * @param ownerEntityName
     * @param inverseSideEntityName
     * @param ownerRelationName
     * @param ownerDisplayField
     * @param ownerComment
     * @param inverseSideComment
     * @param inverseSideRelationName
     * @param inverseSideDisplayField
     * @param comment
     */
    public JdlRelationViewImpl(
        RelationType relationType,
        boolean bidirectional,
        boolean ownerRequired,
        boolean inverseSideRequired,
        String ownerEntityName,
        String inverseSideEntityName,
        String ownerRelationName,
        @Nullable String ownerDisplayField,
        @Nullable String ownerComment,
        @Nullable String inverseSideComment,
        @Nullable String inverseSideRelationName,
        @Nullable String inverseSideDisplayField,
        @Nullable String comment
    ) {
        super(
            relationType,
            bidirectional,
            ownerRequired,
            inverseSideRequired,
            ownerEntityName,
            inverseSideEntityName,
            ownerRelationName,
            ownerDisplayField,
            ownerComment,
            inverseSideComment,
            inverseSideRelationName,
            inverseSideDisplayField,
            comment
        );
    }
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/view/mapper/JdlViewMapper.java
================================================
package org.blackdread.sqltojava.view.mapper;

import org.blackdread.sqltojava.config.UndefinedJdlTypeHandlingEnum;
import org.blackdread.sqltojava.entity.impl.JdlEntityImpl;
import org.blackdread.sqltojava.entity.impl.JdlFieldImpl;
import org.blackdread.sqltojava.entity.impl.JdlRelationGroupImpl;
import org.blackdread.sqltojava.entity.impl.JdlRelationImpl;
import org.blackdread.sqltojava.view.impl.JdlEntityViewImpl;
import org.blackdread.sqltojava.view.impl.JdlFieldViewImpl;
import org.blackdread.sqltojava.view.impl.JdlRelationGroupViewImpl;
import org.blackdread.sqltojava.view.impl.JdlRelationViewImpl;
import org.mapstruct.Mapper;

/**
 * Generate Mapstruct mapper sources on compile
 */
@Mapper(componentModel = "spring", uses = OptionalUtils.class)
public interface JdlViewMapper {
    JdlEntityViewImpl entityToView(JdlEntityImpl jdlEntity, UndefinedJdlTypeHandlingEnum undefinedJdlTypeHandling);
    JdlFieldViewImpl fieldToView(JdlFieldImpl jdlField);
    JdlRelationViewImpl relationToView(JdlRelationImpl jdlRelation);
    JdlRelationGroupViewImpl relationToView(JdlRelationGroupImpl jdlRelation);
}


================================================
FILE: src/main/java/org/blackdread/sqltojava/view/mapper/OptionalUtils.java
================================================
package org.blackdread.sqltojava.view.mapper;

import java.util.Optional;

/**
 * Used to handle Optional with Mapstruct
 */
public class OptionalUtils {

    private OptionalUtils() {}

    public static <T> T fromOptional(Optional<T> optional) {
        return optional.orElse(null);
    }
}


================================================
FILE: src/main/resources/application.yml
================================================
spring:
    datasource:
        type: com.zaxxer.hikari.HikariDataSource
        url: jdbc:mysql://localhost:3306/?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
        username: root
        password:
        hikari:
            data-source-properties:
                cachePrepStmts: true
                prepStmtCacheSize: 250
                prepStmtCacheSqlLimit: 2048
                useServerPrepStmts: true
    flyway:
        enabled: false

application:
    reserved-keywords: classpath:reserved/keywords.json
    database-to-export: dbo
    database_object_types_config: ALL # TABLES, ViEWS, ALL
    render_entities_only: false
    assume_bidirectional: false
    database-object-prefix:
        - t_
        - v_
    add_table_name_jdl: true
    undefined_type_handling: ERROR
    jdl-type-overrides:
        my_type: FLOAT # Example JDL type override
    ignored-table-names:
        - databasechangelog
        - databasechangeloglock
        - QRTZ_BLOB_TRIGGERS
        - QRTZ_CALENDARS
        - QRTZ_CRON_TRIGGERS
        - QRTZ_FIRED_TRIGGERS
        - QRTZ_JOB_DETAILS
        - QRTZ_LOCKS
        - QRTZ_PAUSED_TRIGGER_GRPS
        - QRTZ_SCHEDULER_STATE
        - QRTZ_SIMPLE_TRIGGERS
        - QRTZ_SIMPROP_TRIGGERS
        - QRTZ_TRIGGERS
        - MSreplication_options
        - spt_fallback_db
        - spt_fallback_dev
        - spt_fallback_usg
        - spt_monitor
        - spt_values
    export:
        path: ./my-project-jdl.jh
        type: jdl
        export-file-structure-type: GROUPED_RELATIONS_SEPARATE_VIEWS
        export-mustache-template-filename-optional:


================================================
FILE: src/main/resources/mustache/application-entities-relations-views.mustache
================================================
{{> entities}}

{{> onetoonerelations}}

{{> manytoonerelations}}

{{> manytomanyrelations}}

{{> views}}

{{> viewsrelations}}

{{> options}}


================================================
FILE: src/main/resources/mustache/application-grouped-relations-separate-views.mustache
================================================
{{> entities}}

{{> groupedonetoonerelations}}

{{> groupedmanytoonerelations}}

{{> manytomanyrelations}}

{{> views}}

{{> viewsrelations}}

{{> options}}


================================================
FILE: src/main/resources/mustache/application.mustache
================================================
{{> entities}}

{{> relations}}

{{> options}}


================================================
FILE: src/main/resources/mustache/entities.mustache
================================================
{{#entities}}
{{^value.isPureManyToMany}}
{{#value.comment}}
{{value.docComment}}
{{/value.comment}}
{{#value.isReadOnly}}
@readOnly
{{/value.isReadOnly}}
{{value.type}} {{value.name}}{{value.tableName}} {
{{#value.filteredFields}}
{{#value.comment}}
    {{value.docComment}}
{{/value.comment}}
    {{value.name}} {{value.typeName}}{{value.constraints}}{{^last}},{{/last}}
{{/value.filteredFields}}
}
{{^last}}{{/last}}
{{/value.isPureManyToMany}}
{{/entities}}
{{^entities}}
// No entities were found for which JDL is to be generated. Please review console logs
{{/entities}}

================================================
FILE: src/main/resources/mustache/groupedmanytoonerelations.mustache
================================================
{{#groupedmanytoonerelations}}

{{#first}}// Grouped Relations{{/first}}
{{#isPureManyToMany}}
    // TODO This is a pure ManyToMany relation (delete me and decide owner side)
{{/isPureManyToMany}}
{{#comment}}
    {{implComment}}
{{/comment}}
relationship {{relationType}} {
{{#relations}}
    {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}
{{/relations}}
}
{{/groupedmanytoonerelations}}


================================================
FILE: src/main/resources/mustache/groupedonetoonerelations.mustache
================================================
{{#groupedonetoonerelations}}
{{#first}}// Grouped Relations{{/first}}
{{#isPureManyToMany}}
    // TODO This is a pure ManyToMany relation (delete me and decide owner side)
{{/isPureManyToMany}}
{{#comment}}
    {{implComment}}
{{/comment}}
relationship {{relationType}} {
{{#relations}}
    {{^value.hasComments}}
    {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
    {{#value.hasComments}}
        {{#value.ownerDocComment}}
            {{value.ownerDocComment}}
        {{/value.ownerDocComment}}
        {{value.ownerEntityName}}{{value.ownerConfig}} to
        {{#value.inverseDocComment}}
            {{value.inverseDocComment}}
        {{/value.inverseDocComment}}
        {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
{{/relations}}
}
{{/groupedonetoonerelations}}


================================================
FILE: src/main/resources/mustache/manytomanyrelations.mustache
================================================
{{#manytomanyrelations}}
{{#first}}// many-to-many Relations{{/first}}
{{#value.isPureManyToMany}}
// TODO This is a pure ManyToMany relation (delete me and decide owner side)
{{/value.isPureManyToMany}}
{{#value.comment}}
{{value.implComment}}
{{/value.comment}}
relationship {{value.type}} {
    {{^value.hasComments}}
    {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
    {{#value.hasComments}}
    {{#value.ownerDocComment}}
    {{value.ownerDocComment}}
    {{/value.ownerDocComment}}
    {{value.ownerEntityName}}{{value.ownerConfig}} to
    {{#value.inverseDocComment}}
    {{value.inverseDocComment}}
    {{/value.inverseDocComment}}
    {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
}
{{^last}}{{/last}}
{{/manytomanyrelations}}


================================================
FILE: src/main/resources/mustache/manytoonerelations.mustache
================================================
{{#manytoonerelations}}
    {{#first}}//many-to-one Relations{{/first}}
    {{#value.isPureManyToMany}}
        // TODO This is a pure ManyToMany relation (delete me and decide owner side)
    {{/value.isPureManyToMany}}
    {{#value.comment}}
        {{value.implComment}}
    {{/value.comment}}
    relationship {{value.type}} {
    {{^value.hasComments}}
        {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
    {{#value.hasComments}}
        {{#value.ownerDocComment}}
            {{value.ownerDocComment}}
        {{/value.ownerDocComment}}
        {{value.ownerEntityName}}{{value.ownerConfig}} to
        {{#value.inverseDocComment}}
            {{value.inverseDocComment}}
        {{/value.inverseDocComment}}
        {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
    }
    {{^last}}{{/last}}
{{/manytoonerelations}}


================================================
FILE: src/main/resources/mustache/onetoonerelations.mustache
================================================
{{#onetoonerelations}}
    {{#first}}//one-to-one Relations{{/first}}
    {{#value.isPureManyToMany}}
        // TODO This is a pure ManyToMany relation (delete me and decide owner side)
    {{/value.isPureManyToMany}}
    {{#value.comment}}
        {{value.implComment}}
    {{/value.comment}}
    relationship {{value.type}} {
    {{^value.hasComments}}
        {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
    {{#value.hasComments}}
        {{#value.ownerDocComment}}
            {{value.ownerDocComment}}
        {{/value.ownerDocComment}}
        {{value.ownerEntityName}}{{value.ownerConfig}} to
        {{#value.inverseDocComment}}
            {{value.inverseDocComment}}
        {{/value.inverseDocComment}}
        {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
    }
    {{^last}}{{/last}}
{{/onetoonerelations}}


================================================
FILE: src/main/resources/mustache/options.mustache
================================================
{{#options}}
{{#first}}// Options{{/first}}
{{value}}
{{/options}}


================================================
FILE: src/main/resources/mustache/relations.mustache
================================================
{{#relations}}
{{#first}}// Relations{{/first}}
{{#value.isPureManyToMany}}
// TODO This is a pure ManyToMany relation (delete me and decide owner side)
{{/value.isPureManyToMany}}
{{#value.comment}}
{{value.implComment}}
{{/value.comment}}
relationship {{value.type}} {
    {{^value.hasComments}}
    {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
    {{#value.hasComments}}
    {{#value.ownerDocComment}}
    {{value.ownerDocComment}}
    {{/value.ownerDocComment}}
    {{value.ownerEntityName}}{{value.ownerConfig}} to
    {{#value.inverseDocComment}}
    {{value.inverseDocComment}}
    {{/value.inverseDocComment}}
    {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
}
{{^last}}{{/last}}
{{/relations}}


================================================
FILE: src/main/resources/mustache/views.mustache
================================================
{{#views}}
{{^value.isPureManyToMany}}
{{#value.comment}}
{{value.docComment}}
{{/value.comment}}
{{#value.isReadOnly}}
@readOnly
{{/value.isReadOnly}}
{{value.type}} {{value.name}}{{value.tableName}} {
{{#value.filteredFields}}
{{#value.comment}}
    {{value.docComment}}
{{/value.comment}}
    {{value.name}} {{value.typeName}}{{value.constraints}}{{^last}},{{/last}}
{{/value.filteredFields}}
}
{{^last}}{{/last}}
{{/value.isPureManyToMany}}
{{/views}}
{{^views}}
// No views were found for which JDL is to be generated. Please review console logs
{{/views}}


================================================
FILE: src/main/resources/mustache/viewsrelations.mustache
================================================
{{#viewsrelations}}
{{#first}}// Relations{{/first}}
{{#value.isPureManyToMany}}
// TODO This is a pure ManyToMany relation (delete me and decide owner side)
{{/value.isPureManyToMany}}
{{#value.comment}}
{{value.implComment}}
{{/value.comment}}
relationship {{value.type}} {
    {{^value.hasComments}}
    {{value.ownerEntityName}}{{value.ownerConfig}} to {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
    {{#value.hasComments}}
    {{#value.ownerDocComment}}
    {{value.ownerDocComment}}
    {{/value.ownerDocComment}}
    {{value.ownerEntityName}}{{value.ownerConfig}} to
    {{#value.inverseDocComment}}
    {{value.inverseDocComment}}
    {{/value.inverseDocComment}}
    {{value.inverseSideEntityName}}{{value.inverseConfig}}
    {{/value.hasComments}}
}
{{^last}}{{/last}}
{{/viewsrelations}}


================================================
FILE: src/main/resources/reserved/keywords.json
================================================
{
    "java": [
        "ABSTRACT",
        "CONTINUE",
        "FOR",
        "NEW",
        "SWITCH",
        "ASSERT",
        "DEFAULT",
        "GOTO",
        "PACKAGE",
        "SYNCHRONIZED",
        "BOOLEAN",
        "DO",
        "IF",
        "PRIVATE",
        "THIS",
        "BREAK",
        "DOUBLE",
        "IMPLEMENTS",
        "PROTECTED",
        "THROW",
        "BYTE",
        "ELSE",
        "IMPORT",
        "PUBLIC",
        "THROWS",
        "CASE",
        "ENUM",
        "INSTANCEOF",
        "RETURN",
        "TRANSIENT",
        "CATCH",
        "EXTENDS",
        "INT",
        "SHORT",
        "TRY",
        "CHAR",
        "FINAL",
        "INTERFACE",
        "STATIC",
        "VOID",
        "CLASS",
        "FINALLY",
        "LONG",
        "STRICTFP",
        "VOLATILE",
        "CONST",
        "FLOAT",
        "NATIVE",
        "SUPER",
        "WHILE"
    ],
    "jhipster": [
        "ACCOUNT",
        "ACTIVATE",
        "AUDITS",
        "CONFIGURATION",
        "DOCS",
        "HEALTH",
        "LOGS",
        "METRICS",
        "PASSWORD",
        "REGISTER",
        "RESET",
        "SESSIONS",
        "SETTINGS",
        "TEST",
        "EVENTMANAGER",
        "PRINCIPAL",
        "ENTITY",
        "RESULT"
    ],
    "angular": [
        "CLASS",
        "NODENAME",
        "NODETYPE",
        "COMPONENT",
        "SUBSCRIPTION",
        "RESPONSE",
        "OBSERVABLE",
        "INJECTABLE",
        "HTTP",
        "ROUTER"
    ],
    "typescript": [
        "BREAK",
        "CASE",
        "CATCH",
        "CLASS",
        "CONST",
        "CONSTRUCTOR",
        "CONTINUE",
        "DEBUGGER",
        "DEFAULT",
        "DELETE",
        "DO",
        "ELSE",
        "ENUM",
        "EXPORT",
        "EXTENDS",
        "FALSE",
        "FINALLY",
        "FOR",
        "FUNCTION",
        "IF",
        "IMPORT",
        "IN",
        "INSTANCEOF",
        "NEW",
        "NULL",
        "RETURN",
        "SUPER",
        "SWITCH",
        "THIS",
        "THROW",
        "TRUE",
        "TRY",
        "TYPEOF",
        "VAR",
        "VOID",
        "WHILE",
        "WITH",
        "IMPLEMENTS",
        "INTERFACE",
        "LET",
        "PACKAGE",
        "PRIVATE",
        "PROTECTED",
        "PUBLIC",
        "STATIC",
        "YIELD"
    ]
}


================================================
FILE: src/main/resources/sql/mysql_mariadb-getAllTableInformation.sql
================================================
select t.table_schema,
       t.table_name,
       case
           when v.is_updatable='NO' then false
           else true
           end as is_updatable,
       case
           when t.table_type='VIEW' and t.table_comment='VIEW' then 'view'
           else t.table_comment
       end as comment,
      t.table_type
from information_schema.tables t
left join information_schema.views v on v.table_schema=t.table_schema
                                    and v.table_name=t.table_name
where t.table_schema=:schemaName
order by t.table_schema,
         v.is_updatable,
         t.table_name;


================================================
FILE: src/main/resources/sql/mysql_mariadb-getAllTableRelationInformation.sql
================================================
select kku.constraint_name,
       kku.table_schema,
       kku.table_name,
       kku.column_name,
       kku.referenced_table_schema as foreign_table_schema,
       kku.referenced_table_name   as foreign_table_name,
       kku.referenced_column_name  as foreign_column_name
from information_schema.key_column_usage kku
where kku.referenced_table_schema=:schemaName and kku.referenced_table_name is not null
order by kku.table_name,
         kku.column_name;


================================================
FILE: src/main/resources/sql/mysql_mariadb-getFullColumnInformationOfTable.sql
================================================
select
    c.table_schema,
    c.table_name,
    c.column_name,
    case
        when c.character_maximum_length is null then c.data_type
        else concat(c.data_type, '(', c.character_maximum_length, ')')
    end as data_type,
    c.data_type,
    c.column_default,
    c.is_nullable,
    c.column_comment comment,
    c.column_key 'key',
    c.ordinal_position
from information_schema.columns c
where c.table_schema=:schemaName
  and c.table_name=:tableName
order by c.ordinal_position;


================================================
FILE: src/main/resources/sql/oracle-getAllTableInformation.sql
================================================
select o.OWNER       as schema,
       o.OBJECT_NAME as table_name,
       case
           WHEN v.READ_ONLY = 'Y' THEN 'NO'
           when v.READ_ONLY = 'N' or v.READ_ONLY is null THEN 'YES'
           END       as is_updatable,
       case
           when (o.OBJECT_TYPE = 'VIEW' and tc.COMMENTS is null) then 'view'
           else tc.COMMENTS
           end          "comment",
       case o.OBJECT_TYPE
           when 'VIEW' then 'VIEW'
           when 'TABLE' then 'BASE TABLE'
           end          table_type
from ALL_OBJECTS o
         LEFT JOIN ALL_TABLES t
                   on (o.OWNER = t.OWNER and o.OBJECT_NAME = t.TABLE_NAME and o.OBJECT_TYPE = 'TABLE' AND
                       t.NESTED = 'NO')
         LEFT JOIN ALL_VIEWS v on (o.OWNER = v.OWNER and o.OBJECT_NAME = v.VIE
Download .txt
gitextract_dpof0rjx/

├── .editorconfig
├── .gitattributes
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       └── maven.yml
├── .gitignore
├── .mvn/
│   └── wrapper/
│       ├── maven-wrapper.jar
│       └── maven-wrapper.properties
├── .prettierignore
├── .prettierrc
├── .travis.yml
├── LICENSE
├── README.md
├── checkstyle-suppressions.xml
├── checkstyle.xml
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src/
    ├── main/
    │   ├── java/
    │   │   └── org/
    │   │       └── blackdread/
    │   │           └── sqltojava/
    │   │               ├── SqlToJavaApplication.java
    │   │               ├── config/
    │   │               │   ├── ApplicationProperties.java
    │   │               │   ├── CacheConfiguration.java
    │   │               │   ├── DatabaseObjectTypesConfigEnum.java
    │   │               │   ├── ExportFileStructureType.java
    │   │               │   └── UndefinedJdlTypeHandlingEnum.java
    │   │               ├── entity/
    │   │               │   ├── JdlEntity.java
    │   │               │   ├── JdlField.java
    │   │               │   ├── JdlFieldEnum.java
    │   │               │   ├── JdlRelation.java
    │   │               │   ├── JdlRelationGroup.java
    │   │               │   ├── RelationType.java
    │   │               │   ├── SqlColumn.java
    │   │               │   ├── SqlForeignKey.java
    │   │               │   ├── SqlTable.java
    │   │               │   └── impl/
    │   │               │       ├── JdlEntityImpl.java
    │   │               │       ├── JdlFieldImpl.java
    │   │               │       ├── JdlRelationGroupImpl.java
    │   │               │       ├── JdlRelationImpl.java
    │   │               │       ├── SqlColumnImpl.java
    │   │               │       └── SqlTableImpl.java
    │   │               ├── exporter/
    │   │               │   └── ExportFileStructureConfig.java
    │   │               ├── listener/
    │   │               │   └── SetDatabaseProfileApplicationEventListener.java
    │   │               ├── parser/
    │   │               │   └── SqlParser.java
    │   │               ├── pojo/
    │   │               │   ├── ColumnInformation.java
    │   │               │   ├── TableInformation.java
    │   │               │   ├── TableRelationInformation.java
    │   │               │   └── rowmaper/
    │   │               │       ├── ColumnInformationRowMapper.java
    │   │               │       ├── SqlServerColumnInformationRowMapper.java
    │   │               │       ├── SqlServerTableInformationRowMapper.java
    │   │               │       ├── TableInformationRowMapper.java
    │   │               │       └── TableRelationInformationRowMapper.java
    │   │               ├── repository/
    │   │               │   ├── InformationSchemaRepository.java
    │   │               │   ├── MsSqlPureSqlInformationSchemaRepository.java
    │   │               │   └── PureSqlInformationSchemaRepository.java
    │   │               ├── service/
    │   │               │   ├── InformationSchemaService.java
    │   │               │   ├── MsSqlJdlTypeService.java
    │   │               │   ├── MySqlJdlTypeService.java
    │   │               │   ├── OracleJdlTypeService.java
    │   │               │   ├── PostgresJdlTypeService.java
    │   │               │   ├── SqlJdlTypeService.java
    │   │               │   └── logic/
    │   │               │       ├── ExportService.java
    │   │               │       ├── JdlService.java
    │   │               │       ├── MustacheService.java
    │   │               │       └── SqlService.java
    │   │               ├── util/
    │   │               │   ├── AppUtil.java
    │   │               │   ├── JdbcUtil.java
    │   │               │   ├── JdlUtils.java
    │   │               │   ├── NamingConventionUtil.java
    │   │               │   ├── ResourceUtil.java
    │   │               │   └── SqlUtils.java
    │   │               └── view/
    │   │                   ├── JdlCommentView.java
    │   │                   ├── JdlEntityView.java
    │   │                   ├── JdlFieldView.java
    │   │                   ├── JdlRelationGroupView.java
    │   │                   ├── JdlRelationView.java
    │   │                   ├── impl/
    │   │                   │   ├── JdlEntityViewImpl.java
    │   │                   │   ├── JdlFieldViewImpl.java
    │   │                   │   ├── JdlRelationGroupViewImpl.java
    │   │                   │   └── JdlRelationViewImpl.java
    │   │                   └── mapper/
    │   │                       ├── JdlViewMapper.java
    │   │                       └── OptionalUtils.java
    │   └── resources/
    │       ├── application.yml
    │       ├── mustache/
    │       │   ├── application-entities-relations-views.mustache
    │       │   ├── application-grouped-relations-separate-views.mustache
    │       │   ├── application.mustache
    │       │   ├── entities.mustache
    │       │   ├── groupedmanytoonerelations.mustache
    │       │   ├── groupedonetoonerelations.mustache
    │       │   ├── manytomanyrelations.mustache
    │       │   ├── manytoonerelations.mustache
    │       │   ├── onetoonerelations.mustache
    │       │   ├── options.mustache
    │       │   ├── relations.mustache
    │       │   ├── views.mustache
    │       │   └── viewsrelations.mustache
    │       ├── reserved/
    │       │   └── keywords.json
    │       └── sql/
    │           ├── mysql_mariadb-getAllTableInformation.sql
    │           ├── mysql_mariadb-getAllTableRelationInformation.sql
    │           ├── mysql_mariadb-getFullColumnInformationOfTable.sql
    │           ├── oracle-getAllTableInformation.sql
    │           ├── oracle-getAllTableRelationInformation.sql
    │           ├── oracle-getFullColumnInformationOfTable.sql
    │           ├── postgresql-getAllTableInformation.sql
    │           ├── postgresql-getAllTableRelationInformation.sql
    │           ├── postgresql-getFullColumnInformationOfTable.sql
    │           ├── sqlserver-getAllTableInformation.sql
    │           ├── sqlserver-getAllTableRelationInformation.sql
    │           └── sqlserver-getFullColumnInformationOfTable.sql
    └── test/
        ├── java/
        │   └── org/
        │       └── blackdread/
        │           └── sqltojava/
        │               ├── AssertUtil.java
        │               ├── FileUtil.java
        │               ├── shared/
        │               │   ├── LoggingExtension.java
        │               │   ├── MainApplicationContextLoader.java
        │               │   ├── interfaces/
        │               │   │   ├── CompareJdlResultsTest.java
        │               │   │   ├── ContainersStartedTest.java
        │               │   │   ├── EnvironmentTest.java
        │               │   │   ├── JdbcContainerTest.java
        │               │   │   ├── LoggingTest.java
        │               │   │   └── ProfileActiveTest.java
        │               │   └── tests/
        │               │       ├── BaseJdbcContainerTest.java
        │               │       ├── SqlToJdlTransactionPerTestTest.java
        │               │       └── TransactionPerTestTest.java
        │               └── test/
        │                   ├── db/
        │                   │   ├── mssql/
        │                   │   │   └── MssqlSql2019Test.java
        │                   │   ├── mysql/
        │                   │   │   ├── MariaDBLatestTest.java
        │                   │   │   ├── Mysql57Test.java
        │                   │   │   ├── Mysql8Test.java
        │                   │   │   ├── Mysql9Test.java
        │                   │   │   └── MysqlLatestTest.java
        │                   │   ├── oracle/
        │                   │   │   └── OracleLatestTest.java
        │                   │   └── postgres/
        │                   │       ├── Postgres09Test.java
        │                   │       ├── Postgres10Test.java
        │                   │       ├── Postgres15Test.java
        │                   │       ├── Postgres17Test.java
        │                   │       ├── PostgresAddTableNameJdlTest.java
        │                   │       ├── PostgresDatabaseObjectPrefixTest.java
        │                   │       ├── PostgresLatestTest.java
        │                   │       └── PostgresOverrideJdlTypeTest.java
        │                   └── general/
        │                       ├── DatabaseObjectPrefixTest.java
        │                       ├── MustacheTest.java
        │                       ├── unsupported/
        │                       │   ├── PostgresUndefinedErrorTest.java
        │                       │   ├── PostgresUndefinedSkioTest.java
        │                       │   └── PostgresUndefinedUnsupportedTest.java
        │                       └── views/
        │                           └── PostgresDatabaseObjectTypesTest.java
        └── resources/
            ├── application.yml
            ├── container-license-acceptance.txt
            ├── db/
            │   └── changelog/
            │       └── db.changelog-master.yaml
            ├── jdl/
            │   ├── all_jdl_types-expected.jdl
            │   ├── all_types-expected-mariadb.jdl
            │   ├── all_types-expected-mysql.jdl
            │   ├── all_types-expected-oracle.jdl
            │   ├── all_types-expected-postgresql.jdl
            │   ├── all_types-expected-sqlserver.jdl
            │   ├── all_types-liquibase-changeset-sqlserver.yaml
            │   ├── all_types-liquibase-changeset.yaml
            │   ├── display_field_many_to_one-expected-sqlserver.jdl
            │   ├── display_field_many_to_one-expected.jdl
            │   ├── display_field_many_to_one-liquibase-changeset.yaml
            │   ├── duplicate_names-expected.jdl
            │   ├── duplicate_names-liquibase-changeset.yaml
            │   ├── enum-expected-sqlserver.jdl
            │   ├── enum-expected.jdl
            │   ├── enum-liquibase-changeset-sqlserver.yaml
            │   ├── enum-liquibase-changeset.yaml
            │   ├── many_to_one-expected.jdl
            │   ├── many_to_one-liquibase-changeset.yaml
            │   ├── one_to_one-expected.jdl
            │   ├── one_to_one-liquibase-changeset.yaml
            │   ├── one_to_one_main_map-expected.jdl
            │   ├── one_to_one_main_map-liquibase-changeset.yaml
            │   ├── override_jdl_types-expected-postgresql.jdl
            │   ├── override_jdl_types-liquibase-changeset.yaml
            │   ├── parent_child-expected.jdl
            │   ├── parent_child-liquibase-changeset.yaml
            │   ├── prefix-expected.jdl
            │   ├── prefix-liquibase-changeset.yaml
            │   ├── prune-expected.jdl
            │   ├── prune-liquibase-changeset.yaml
            │   ├── readonly-expected-sqlserver.jdl
            │   ├── readonly-expected.jdl
            │   ├── readonly-liquibase-changeset.yaml
            │   ├── reflexive_relationship-expected.jdl
            │   ├── reflexive_relationship-liquibase-changeset.yaml
            │   ├── table_name-expected.jdl
            │   ├── table_name-liquibase-changeset.yaml
            │   ├── tables-only-expected.jdl
            │   ├── tables-only-liquibase-changeset.yaml
            │   ├── undefined_error-expected.jdl
            │   ├── undefined_error-liquibase-changeset.yaml
            │   ├── undefined_skip-expected.jdl
            │   ├── undefined_skip-liquibase-changeset.yaml
            │   ├── undefined_unsupported-expected.jdl
            │   ├── undefined_unsupported-liquibase-changeset.yaml
            │   ├── unique-expected-oracle.jdl
            │   ├── unique-expected-sqlserver.jdl
            │   ├── unique-expected.jdl
            │   ├── unique-liquibase-changeset.yaml
            │   ├── uuid_id_required-expected-mariadb.jdl
            │   ├── uuid_id_required-expected-mysql.jdl
            │   ├── uuid_id_required-expected-postgresql.jdl
            │   ├── uuid_id_required-expected-sqlserver.jdl
            │   ├── uuid_id_required-expected.jdl
            │   ├── uuid_id_required-liquibase-changeset-sqlserver.yaml
            │   ├── uuid_id_required-liquibase-changeset.yaml
            │   ├── views-expected.jdl
            │   └── views-liquibase-changeset.yaml
            └── liquibase.properties
Download .txt
SYMBOL INDEX (492 symbols across 96 files)

FILE: src/main/java/org/blackdread/sqltojava/SqlToJavaApplication.java
  class SqlToJavaApplication (line 18) | @EnableConfigurationProperties(ApplicationProperties.class)
    method SqlToJavaApplication (line 32) | public SqlToJavaApplication(
    method main (line 44) | public static void main(String[] args) {
    method run (line 49) | @Override

FILE: src/main/java/org/blackdread/sqltojava/config/ApplicationProperties.java
  class ApplicationProperties (line 20) | @ConstructorBinding
    method ApplicationProperties (line 41) | @SuppressWarnings("unchecked")
    method getDatabaseToExport (line 77) | public String getDatabaseToExport() {
    method getIgnoredTableNames (line 81) | public List<String> getIgnoredTableNames() {
    method getExport (line 85) | public Export getExport() {
    method getReservedList (line 89) | public List<String> getReservedList() {
    method getAddTableNameJdl (line 93) | public Boolean getAddTableNameJdl() {
    method getUndefinedTypeHandling (line 97) | public UndefinedJdlTypeHandlingEnum getUndefinedTypeHandling() {
    method getDatabaseObjectTypesConfig (line 101) | public DatabaseObjectTypesConfigEnum getDatabaseObjectTypesConfig() {
    method isRenderEntitiesOnly (line 105) | public Boolean isRenderEntitiesOnly() {
    method isAssumeBidirectional (line 109) | public Boolean isAssumeBidirectional() {
    method getDatabaseObjectPrefix (line 113) | public List<String> getDatabaseObjectPrefix() {
    method getJdlTypeOverrides (line 117) | public Map<String, JdlFieldEnum> getJdlTypeOverrides() {
    class Export (line 121) | public static class Export {
      method Export (line 129) | public Export(
      method getPath (line 141) | public Path getPath() {
      method getType (line 145) | public String getType() {
      method getExportFileStructureType (line 149) | public ExportFileStructureType getExportFileStructureType() {
      method getExportMustacheTemplateFilenameOptional (line 153) | public String getExportMustacheTemplateFilenameOptional() {
    method keywordsAsJson (line 158) | private String keywordsAsJson(String file) {

FILE: src/main/java/org/blackdread/sqltojava/config/CacheConfiguration.java
  class CacheConfiguration (line 9) | @Configuration
    method cacheManager (line 13) | @Bean

FILE: src/main/java/org/blackdread/sqltojava/config/DatabaseObjectTypesConfigEnum.java
  type DatabaseObjectTypesConfigEnum (line 3) | public enum DatabaseObjectTypesConfigEnum {

FILE: src/main/java/org/blackdread/sqltojava/config/ExportFileStructureType.java
  type ExportFileStructureType (line 3) | public enum ExportFileStructureType {
    method ExportFileStructureType (line 17) | ExportFileStructureType(String exportMustacheTemplateFilename, String ...
    method getExportMustacheTemplateFilename (line 22) | public String getExportMustacheTemplateFilename() {
    method getComment (line 26) | public String getComment() {

FILE: src/main/java/org/blackdread/sqltojava/config/UndefinedJdlTypeHandlingEnum.java
  type UndefinedJdlTypeHandlingEnum (line 6) | public enum UndefinedJdlTypeHandlingEnum {

FILE: src/main/java/org/blackdread/sqltojava/entity/JdlEntity.java
  type JdlEntity (line 6) | public interface JdlEntity {
    method getName (line 7) | String getName();
    method getTableName (line 9) | String getTableName();
    method getFields (line 11) | List<JdlField> getFields();
    method isReadOnly (line 17) | boolean isReadOnly();
    method getComment (line 19) | Optional<String> getComment();
    method isEnumEntity (line 21) | boolean isEnumEntity();
    method isPureManyToMany (line 28) | boolean isPureManyToMany();
    method getRelations (line 33) | List<JdlRelation> getRelations();

FILE: src/main/java/org/blackdread/sqltojava/entity/JdlField.java
  type JdlField (line 5) | public interface JdlField {
    method getType (line 6) | JdlFieldEnum getType();
    method getName (line 8) | String getName();
    method getEnumEntityName (line 13) | Optional<String> getEnumEntityName();
    method isNativeEnum (line 21) | boolean isNativeEnum();
    method isRequired (line 23) | boolean isRequired();
    method getComment (line 25) | Optional<String> getComment();
    method getMin (line 32) | Optional<Integer> getMin();
    method getMax (line 39) | Optional<Integer> getMax();
    method getPattern (line 41) | Optional<String> getPattern();
    method isUnique (line 46) | boolean isUnique();
    method isPrimaryKey (line 51) | boolean isPrimaryKey();

FILE: src/main/java/org/blackdread/sqltojava/entity/JdlFieldEnum.java
  type JdlFieldEnum (line 5) | public enum JdlFieldEnum {
    method toCamelUpper (line 58) | public String toCamelUpper() {

FILE: src/main/java/org/blackdread/sqltojava/entity/JdlRelation.java
  type JdlRelation (line 5) | public interface JdlRelation {
    method getRelationType (line 6) | RelationType getRelationType();
    method isBidirectional (line 8) | boolean isBidirectional();
    method isOwnerRequired (line 10) | boolean isOwnerRequired();
    method isInverseSideRequired (line 12) | boolean isInverseSideRequired();
    method getOwnerComment (line 16) | Optional<String> getOwnerComment();
    method getInverseSideComment (line 18) | Optional<String> getInverseSideComment();
    method getComment (line 25) | Optional<String> getComment();
    method getOwnerEntityName (line 32) | String getOwnerEntityName();
    method getInverseSideEntityName (line 39) | String getInverseSideEntityName();
    method getOwnerRelationName (line 44) | String getOwnerRelationName();
    method getInverseSideRelationName (line 51) | Optional<String> getInverseSideRelationName();
    method getOwnerDisplayField (line 58) | Optional<String> getOwnerDisplayField();
    method getInverseSideDisplayField (line 65) | Optional<String> getInverseSideDisplayField();

FILE: src/main/java/org/blackdread/sqltojava/entity/JdlRelationGroup.java
  type JdlRelationGroup (line 5) | public interface JdlRelationGroup {
    method getRelationType (line 6) | RelationType getRelationType();
    method getRelations (line 7) | List<JdlRelation> getRelations();

FILE: src/main/java/org/blackdread/sqltojava/entity/RelationType.java
  type RelationType (line 3) | public enum RelationType {
    method toJdl (line 18) | public String toJdl() {

FILE: src/main/java/org/blackdread/sqltojava/entity/SqlColumn.java
  type SqlColumn (line 5) | public interface SqlColumn {
    method getTable (line 6) | SqlTable getTable();
    method getName (line 11) | String getName();
    method getType (line 18) | String getType();
    method isPrimaryKey (line 20) | boolean isPrimaryKey();
    method isForeignKey (line 22) | boolean isForeignKey();
    method isNullable (line 24) | boolean isNullable();
    method isUnique (line 26) | boolean isUnique();
    method isNativeEnum (line 33) | boolean isNativeEnum();
    method getDefaultValue (line 35) | Optional<String> getDefaultValue();
    method getComment (line 37) | Optional<String> getComment();

FILE: src/main/java/org/blackdread/sqltojava/entity/SqlForeignKey.java
  type SqlForeignKey (line 3) | public interface SqlForeignKey {}

FILE: src/main/java/org/blackdread/sqltojava/entity/SqlTable.java
  type SqlTable (line 5) | public interface SqlTable {
    method getName (line 6) | String getName();
    method getComment (line 7) | Optional<String> getComment();
    method isUpdatable (line 8) | boolean isUpdatable();
    method getType (line 9) | String getType();

FILE: src/main/java/org/blackdread/sqltojava/entity/impl/JdlEntityImpl.java
  class JdlEntityImpl (line 14) | @Immutable
    method JdlEntityImpl (line 34) | public JdlEntityImpl(
    method getName (line 54) | @Override
    method getTableName (line 59) | @Override
    method getFields (line 64) | @Override
    method getComment (line 69) | @Override
    method isEnumEntity (line 74) | @Override
    method isReadOnly (line 79) | @Override
    method isPureManyToMany (line 84) | @Override
    method getRelations (line 89) | @Override
    method toString (line 94) | @Override
    method compareTo (line 119) | @Override

FILE: src/main/java/org/blackdread/sqltojava/entity/impl/JdlFieldImpl.java
  class JdlFieldImpl (line 11) | @Immutable
    method JdlFieldImpl (line 27) | public JdlFieldImpl(
    method getType (line 53) | @Override
    method getName (line 58) | @Override
    method getEnumEntityName (line 63) | @Override
    method isRequired (line 68) | @Override
    method getComment (line 73) | @Override
    method getMin (line 78) | @Override
    method getMax (line 83) | @Override
    method getPattern (line 88) | @Override
    method isUnique (line 93) | @Override
    method isPrimaryKey (line 98) | @Override
    method isNativeEnum (line 103) | @Override
    method toString (line 108) | @Override

FILE: src/main/java/org/blackdread/sqltojava/entity/impl/JdlRelationGroupImpl.java
  class JdlRelationGroupImpl (line 12) | @Immutable
    method JdlRelationGroupImpl (line 19) | public JdlRelationGroupImpl(RelationType relationType, List<JdlRelatio...
    method getRelationType (line 24) | public RelationType getRelationType() {
    method getRelations (line 28) | public List<JdlRelation> getRelations() {
    method compareTo (line 32) | @Override
    method toString (line 37) | @Override

FILE: src/main/java/org/blackdread/sqltojava/entity/impl/JdlRelationImpl.java
  class JdlRelationImpl (line 11) | @Immutable
    method JdlRelationImpl (line 34) | public JdlRelationImpl(
    method getRelationType (line 75) | @Override
    method isBidirectional (line 80) | @Override
    method isOwnerRequired (line 85) | @Override
    method isInverseSideRequired (line 90) | @Override
    method getOwnerComment (line 95) | @Override
    method getInverseSideComment (line 100) | @Override
    method getComment (line 105) | @Override
    method getOwnerEntityName (line 110) | @Override
    method getInverseSideEntityName (line 115) | @Override
    method getOwnerRelationName (line 120) | @Override
    method getInverseSideRelationName (line 125) | @Override
    method getOwnerDisplayField (line 130) | @Override
    method getInverseSideDisplayField (line 135) | @Override
    method compareTo (line 140) | @Override

FILE: src/main/java/org/blackdread/sqltojava/entity/impl/SqlColumnImpl.java
  class SqlColumnImpl (line 10) | public class SqlColumnImpl implements SqlColumn {
    method SqlColumnImpl (line 32) | public SqlColumnImpl(
    method getTable (line 56) | @Override
    method getName (line 61) | @Override
    method getType (line 66) | @Override
    method isPrimaryKey (line 71) | @Override
    method isForeignKey (line 76) | @Override
    method isNullable (line 81) | @Override
    method isUnique (line 86) | @Override
    method isNativeEnum (line 91) | @Override
    method getDefaultValue (line 96) | @Override
    method getComment (line 101) | @Override
    method equals (line 106) | @Override
    method hashCode (line 114) | @Override
    method toString (line 119) | @Override

FILE: src/main/java/org/blackdread/sqltojava/entity/impl/SqlTableImpl.java
  class SqlTableImpl (line 9) | public class SqlTableImpl implements SqlTable, Comparable<SqlTable> {
    method SqlTableImpl (line 16) | public SqlTableImpl(final String name, @Nullable final String comment,...
    method getName (line 23) | @Override
    method getComment (line 28) | @Override
    method getType (line 33) | @Override
    method isUpdatable (line 38) | @Override
    method equals (line 43) | @Override
    method hashCode (line 51) | @Override
    method toString (line 56) | @Override
    method compareTo (line 61) | @Override

FILE: src/main/java/org/blackdread/sqltojava/exporter/ExportFileStructureConfig.java
  class ExportFileStructureConfig (line 8) | @Service
    method ExportFileStructureConfig (line 15) | public ExportFileStructureConfig(ApplicationProperties applicationProp...
    method getExportMustacheTemplateFilename (line 23) | public String getExportMustacheTemplateFilename() {
    method getExportFileStructureType (line 27) | public ExportFileStructureType getExportFileStructureType() {

FILE: src/main/java/org/blackdread/sqltojava/listener/SetDatabaseProfileApplicationEventListener.java
  class SetDatabaseProfileApplicationEventListener (line 10) | public class SetDatabaseProfileApplicationEventListener implements Appli...
    method onApplicationEvent (line 14) | @Override

FILE: src/main/java/org/blackdread/sqltojava/parser/SqlParser.java
  class SqlParser (line 6) | public class SqlParser {
    method parse (line 12) | public static void parse(final File fileToParse, final File saveInto) {
    method checkIsSql (line 16) | private static void checkIsSql(final File file) {

FILE: src/main/java/org/blackdread/sqltojava/pojo/ColumnInformation.java
  class ColumnInformation (line 6) | public class ColumnInformation {
    method ColumnInformation (line 17) | public ColumnInformation(
    method ColumnInformation (line 41) | public ColumnInformation(
    method getName (line 62) | public String getName() {
    method getType (line 66) | public String getType() {
    method isNullable (line 70) | public boolean isNullable() {
    method isPrimary (line 74) | public boolean isPrimary() {
    method isUnique (line 78) | public boolean isUnique() {
    method getDefaultValue (line 82) | public Optional<String> getDefaultValue() {
    method getOrdinalPosition (line 86) | public int getOrdinalPosition() {
    method getComment (line 90) | public String getComment() {
    method toString (line 94) | @Override

FILE: src/main/java/org/blackdread/sqltojava/pojo/TableInformation.java
  class TableInformation (line 7) | public class TableInformation {
    method TableInformation (line 15) | public TableInformation(final String name, final boolean isUpdateable,...
    method getName (line 22) | public String getName() {
    method getComment (line 26) | public Optional<String> getComment() {
    method getSchema (line 30) | public String getSchema() {
    method isUpdateable (line 34) | public Boolean isUpdateable() {
    method getType (line 38) | public String getType() {
    method toString (line 42) | @Override
    method equals (line 47) | @Override
    method hashCode (line 55) | @Override

FILE: src/main/java/org/blackdread/sqltojava/pojo/TableRelationInformation.java
  class TableRelationInformation (line 5) | public class TableRelationInformation {
    method TableRelationInformation (line 12) | public TableRelationInformation(
    method getTableName (line 24) | public String getTableName() {
    method getColumnName (line 28) | public String getColumnName() {
    method getReferencedTableName (line 32) | public String getReferencedTableName() {
    method getReferencedColumnName (line 36) | public String getReferencedColumnName() {
    method equals (line 40) | @Override
    method hashCode (line 53) | @Override
    method toString (line 58) | @Override

FILE: src/main/java/org/blackdread/sqltojava/pojo/rowmaper/ColumnInformationRowMapper.java
  class ColumnInformationRowMapper (line 8) | public class ColumnInformationRowMapper implements RowMapper<ColumnInfor...
    method mapRow (line 10) | @Override

FILE: src/main/java/org/blackdread/sqltojava/pojo/rowmaper/SqlServerColumnInformationRowMapper.java
  class SqlServerColumnInformationRowMapper (line 8) | public class SqlServerColumnInformationRowMapper implements RowMapper<Co...
    method mapRow (line 10) | @Override

FILE: src/main/java/org/blackdread/sqltojava/pojo/rowmaper/SqlServerTableInformationRowMapper.java
  class SqlServerTableInformationRowMapper (line 8) | public class SqlServerTableInformationRowMapper implements RowMapper<Tab...
    method mapRow (line 10) | @Override

FILE: src/main/java/org/blackdread/sqltojava/pojo/rowmaper/TableInformationRowMapper.java
  class TableInformationRowMapper (line 8) | public class TableInformationRowMapper implements RowMapper<TableInforma...
    method mapRow (line 10) | @Override

FILE: src/main/java/org/blackdread/sqltojava/pojo/rowmaper/TableRelationInformationRowMapper.java
  class TableRelationInformationRowMapper (line 8) | public class TableRelationInformationRowMapper implements RowMapper<Tabl...
    method mapRow (line 10) | @Override

FILE: src/main/java/org/blackdread/sqltojava/repository/InformationSchemaRepository.java
  type InformationSchemaRepository (line 8) | public interface InformationSchemaRepository {
    method getAllTableRelationInformation (line 9) | List<TableRelationInformation> getAllTableRelationInformation(final St...
    method getFullColumnInformationOfTable (line 10) | List<ColumnInformation> getFullColumnInformationOfTable(final String d...
    method getAllTableInformation (line 11) | List<TableInformation> getAllTableInformation(final String dbName);

FILE: src/main/java/org/blackdread/sqltojava/repository/MsSqlPureSqlInformationSchemaRepository.java
  class MsSqlPureSqlInformationSchemaRepository (line 29) | @Repository
    method MsSqlPureSqlInformationSchemaRepository (line 40) | @Autowired
    method getAllTableRelationInformation (line 49) | @Override
    method getFullColumnInformationOfTable (line 55) | @Override
    method getAllTableInformation (line 61) | public List<TableInformation> getAllTableInformation(final String sche...
    method readSqlFileByProfile (line 75) | private String readSqlFileByProfile(String activeProfile, String query...

FILE: src/main/java/org/blackdread/sqltojava/repository/PureSqlInformationSchemaRepository.java
  class PureSqlInformationSchemaRepository (line 24) | @Repository
    method PureSqlInformationSchemaRepository (line 35) | @Autowired
    method getAllTableRelationInformation (line 44) | @Override
    method getFullColumnInformationOfTable (line 50) | @Override
    method getAllTableInformation (line 56) | public List<TableInformation> getAllTableInformation(final String sche...
    method readSqlFileByProfile (line 70) | private String readSqlFileByProfile(String activeProfile, String query...

FILE: src/main/java/org/blackdread/sqltojava/service/InformationSchemaService.java
  class InformationSchemaService (line 15) | @Service
    method InformationSchemaService (line 25) | public InformationSchemaService(
    method getAllTableRelationInformation (line 33) | @Cacheable("InformationSchemaService.getAllTableRelationInformation")
    method getFullColumnInformationOfTable (line 39) | @Cacheable("InformationSchemaService.getFullColumnInformationOfTable")
    method getAllTableInformation (line 45) | @Cacheable("InformationSchemaService.getAllTableInformation")

FILE: src/main/java/org/blackdread/sqltojava/service/MsSqlJdlTypeService.java
  class MsSqlJdlTypeService (line 23) | @Service
    method MsSqlJdlTypeService (line 34) | public MsSqlJdlTypeService(ApplicationProperties properties) {
    method getTypeMap (line 70) | @Override
    method sqlTypeToJdlType (line 75) | @Override
    method calculateStringMaxLength (line 97) | @Override

FILE: src/main/java/org/blackdread/sqltojava/service/MySqlJdlTypeService.java
  class MySqlJdlTypeService (line 14) | @Service
    method MySqlJdlTypeService (line 22) | public MySqlJdlTypeService(ApplicationProperties properties) {
    method getTypeMap (line 68) | @Override

FILE: src/main/java/org/blackdread/sqltojava/service/OracleJdlTypeService.java
  class OracleJdlTypeService (line 14) | @Service
    method OracleJdlTypeService (line 22) | public OracleJdlTypeService(ApplicationProperties properties) {
    method getTypeMap (line 42) | @Override

FILE: src/main/java/org/blackdread/sqltojava/service/PostgresJdlTypeService.java
  class PostgresJdlTypeService (line 14) | @Service
    method PostgresJdlTypeService (line 22) | public PostgresJdlTypeService(ApplicationProperties properties) {
    method getTypeMap (line 54) | @Override

FILE: src/main/java/org/blackdread/sqltojava/service/SqlJdlTypeService.java
  type SqlJdlTypeService (line 13) | public interface SqlJdlTypeService {
    method getTypeMap (line 14) | Map<String, JdlFieldEnum> getTypeMap();
    method sqlTypeToJdlType (line 16) | default JdlFieldEnum sqlTypeToJdlType(final String sqlType) {
    method mergeOverrides (line 23) | default Map<String, JdlFieldEnum> mergeOverrides(
    method calculateStringMaxLength (line 32) | default Integer calculateStringMaxLength(SqlColumn column) {

FILE: src/main/java/org/blackdread/sqltojava/service/logic/ExportService.java
  class ExportService (line 23) | @Service
    method ExportService (line 35) | public ExportService(
    method exportString (line 52) | public String exportString(final List<JdlEntity> entities) {
    method resolveExportStructure (line 59) | public Map<String, Object> resolveExportStructure(final List<JdlEntity...
    method extractViews (line 100) | private static List<JdlEntity> extractViews(List<JdlEntity> entities) {
    method extractTables (line 104) | private static List<JdlEntity> extractTables(List<JdlEntity> entities) {
    method export (line 113) | public void export(final List<JdlEntity> entities) {

FILE: src/main/java/org/blackdread/sqltojava/service/logic/JdlService.java
  class JdlService (line 22) | @Service
    method JdlService (line 33) | public JdlService(final SqlService sqlService, final ApplicationProper...
    method buildEntities (line 39) | public List<JdlEntity> buildEntities() {
    method getRelations (line 53) | public List<JdlRelation> getRelations(List<JdlEntity> entities) {
    method getOneToOneRelations (line 57) | public List<JdlRelation> getOneToOneRelations(List<JdlEntity> entities) {
    method getManyToOneRelations (line 65) | public List<JdlRelation> getManyToOneRelations(List<JdlEntity> entitie...
    method getGroupManyToOneRelations (line 73) | public JdlRelationGroupImpl getGroupManyToOneRelations(List<JdlEntity>...
    method getGroupOneToOneRelations (line 83) | public JdlRelationGroupImpl getGroupOneToOneRelations(List<JdlEntity> ...
    method getManyToManyRelations (line 93) | public List<JdlRelation> getManyToManyRelations(List<JdlEntity> entiti...
    method nonDefaultPrimaryKeyFields (line 101) | private boolean nonDefaultPrimaryKeyFields(final JdlField f) {
    method isDefaultPrimaryKey (line 105) | private boolean isDefaultPrimaryKey(JdlField f) {
    method buildEntity (line 109) | protected Optional<JdlEntity> buildEntity(final Map.Entry<SqlTable, Li...
    method getEntityNameFormatted (line 161) | private String getEntityNameFormatted(final String name) {
    method buildField (line 169) | protected Optional<JdlField> buildField(final SqlColumn column) {
    method buildRelation (line 270) | protected Optional<JdlRelation> buildRelation(
    method buildInverseSideRelationName (line 360) | private String buildInverseSideRelationName(

FILE: src/main/java/org/blackdread/sqltojava/service/logic/MustacheService.java
  class MustacheService (line 22) | @Service
    method MustacheService (line 31) | public MustacheService(ApplicationProperties properties) {
    method executeTemplate (line 42) | public String executeTemplate(String template, Map<String, Object> con...
    method replaceMultpleBlankLinesWithOne (line 53) | private String replaceMultpleBlankLinesWithOne(String s) {
    method getMustacheFactory (line 61) | private MustacheFactory getMustacheFactory() {
    class MapstructBasedObjectHandler (line 70) | private class MapstructBasedObjectHandler extends ReflectionObjectHand...
      method coerce (line 74) | @Override

FILE: src/main/java/org/blackdread/sqltojava/service/logic/SqlService.java
  class SqlService (line 26) | @Service
    method SqlService (line 36) | @Autowired
    method buildTables (line 44) | @Cacheable("SqlService.buildTables")
    method includeType (line 58) | private boolean includeType(TableInformation table, DatabaseObjectType...
    method doesTableEndWithDetailKeyword (line 66) | private boolean doesTableEndWithDetailKeyword(TableInformation table) {
    method buildColumns (line 80) | @Cacheable("SqlService.buildColumns")
    method getTableOfForeignKey (line 115) | @Cacheable("SqlService.getTableOfForeignKey")
    method getDisplayFieldOfTable (line 136) | @Cacheable("SqlService.getDisplayFieldOfTable")
    method isEnumTable (line 151) | @Cacheable("SqlService.isEnumTable")
    method getEnumValues (line 175) | @Cacheable("SqlService.getEnumValuesForTable")
    method getEnumValues (line 188) | @Cacheable("SqlService.getEnumValuesForColumn")
    method isForeignKeyFromAnEnumTable (line 200) | @Cacheable("SqlService.isForeignKeyFromAnEnumTable")
    method isForeignKey (line 211) | @Cacheable("SqlService.isForeignKey")
    method isPureManyToManyTable (line 227) | @Cacheable("SqlService.isPureManyToManyTable")
    method isTableIgnored (line 240) | private boolean isTableIgnored(final List<String> ignoredTableNames, f...

FILE: src/main/java/org/blackdread/sqltojava/util/AppUtil.java
  class AppUtil (line 6) | public final class AppUtil {
    method setup (line 15) | public static SpringApplication setup(SpringApplication app) {

FILE: src/main/java/org/blackdread/sqltojava/util/JdbcUtil.java
  class JdbcUtil (line 3) | public final class JdbcUtil {
    method getDatabaseTypeFromJdbcUrl (line 10) | public static String getDatabaseTypeFromJdbcUrl(String jdbcUrl) {

FILE: src/main/java/org/blackdread/sqltojava/util/JdlUtils.java
  class JdlUtils (line 10) | public final class JdlUtils {
    method JdlUtils (line 14) | private JdlUtils() {}
    method paginationAll (line 16) | @NotNull
    method serviceClassAll (line 21) | @NotNull
    method mapStructAll (line 26) | @NotNull
    method angularSuffixAll (line 31) | @NotNull
    method filterAll (line 36) | @NotNull
    method getEntityName (line 41) | public static String getEntityName(String name, List<String> prefixes) {
    method decapitalize (line 51) | public static String decapitalize(String string) {
    method getOptions (line 57) | public static List<String> getOptions() {

FILE: src/main/java/org/blackdread/sqltojava/util/NamingConventionUtil.java
  class NamingConventionUtil (line 6) | public final class NamingConventionUtil {
    method replaceSlavenChars (line 8) | public static String replaceSlavenChars(String columnName) {
    method toTitleCase (line 24) | public static String toTitleCase(String sentence) {

FILE: src/main/java/org/blackdread/sqltojava/util/ResourceUtil.java
  class ResourceUtil (line 13) | public final class ResourceUtil {
    method readString (line 17) | public static String readString(Resource resource) {
    method readString (line 25) | public static String readString(String path) {
    method getFirstExistingResourcePath (line 35) | public static String getFirstExistingResourcePath(String fileName, Str...

FILE: src/main/java/org/blackdread/sqltojava/util/SqlUtils.java
  class SqlUtils (line 20) | public final class SqlUtils {
    method SqlUtils (line 26) | private SqlUtils() {}
    method removeIdFromEnd (line 32) | public static String removeIdFromEnd(final String value) {
    method changeToCamelCase (line 38) | public static String changeToCamelCase(final String value) {
    method changeIdToLowerCase (line 54) | public static String changeIdToLowerCase(final String value) {
    method groupColumnsByTable (line 64) | public static Map<SqlTable, List<SqlColumn>> groupColumnsByTable(final...
    method parseSqlSize (line 68) | public static Optional<Integer> parseSqlSize(String value) {
    method parseSqlType (line 84) | public static String parseSqlType(String value) {

FILE: src/main/java/org/blackdread/sqltojava/view/JdlCommentView.java
  type JdlCommentView (line 8) | public interface JdlCommentView {
    method getComment (line 9) | Optional<String> getComment();
    method getImplComment (line 11) | default String getImplComment(String comment) {
    method getDocComment (line 15) | default String getDocComment(String comment) {
    method getDocComment (line 19) | default String getDocComment() {
    method getImplComment (line 23) | default String getImplComment() {

FILE: src/main/java/org/blackdread/sqltojava/view/JdlEntityView.java
  type JdlEntityView (line 15) | public interface JdlEntityView extends JdlEntity, JdlCommentView {
    method getUndefinedJdlTypeHandling (line 16) | UndefinedJdlTypeHandlingEnum getUndefinedJdlTypeHandling();
    method getType (line 18) | default String getType() {
    method tableName (line 22) | default String tableName() {
    method filteredFields (line 26) | default List<JdlField> filteredFields() {
    method filterUnsupported (line 35) | default boolean filterUnsupported(UndefinedJdlTypeHandlingEnum undefin...
    method log (line 62) | private static Logger log() {

FILE: src/main/java/org/blackdread/sqltojava/view/JdlFieldView.java
  type JdlFieldView (line 13) | public interface JdlFieldView extends JdlField, JdlCommentView {
    method getTypeName (line 15) | default String getTypeName() {
    method constraints (line 24) | default String constraints() {
    method renderRequired (line 35) | default boolean renderRequired() {
    method requiredConstraint (line 40) | @NotNull
    method uniqueConstraint (line 45) | @NotNull
    method minConstraint (line 50) | default String minConstraint(int min) {
    method maxConstraint (line 57) | default String maxConstraint(int max) {
    method patternConstraint (line 65) | default String patternConstraint(String pattern) {
    method validationMax (line 72) | @NotNull
    method validationMin (line 77) | @NotNull
    method validationMaxLength (line 82) | default String validationMaxLength(final int max) {
    method validationMinLength (line 86) | @NotNull
    method validationPattern (line 91) | @NotNull

FILE: src/main/java/org/blackdread/sqltojava/view/JdlRelationGroupView.java
  type JdlRelationGroupView (line 6) | @Immutable

FILE: src/main/java/org/blackdread/sqltojava/view/JdlRelationView.java
  type JdlRelationView (line 10) | public interface JdlRelationView extends JdlRelation, JdlCommentView {
    method getType (line 11) | default String getType() {
    method isPureManyToMany (line 15) | default boolean isPureManyToMany() {
    method getOwnerDocComment (line 19) | default String getOwnerDocComment() {
    method hasComments (line 23) | default boolean hasComments() {
    method getInverseDocComment (line 27) | default String getInverseDocComment() {
    method getOwnerConfig (line 31) | default String getOwnerConfig() {
    method getInverseConfig (line 35) | default String getInverseConfig() {
    method getDisplayField (line 48) | default String getDisplayField(Optional<String> relation) {
    method getRelationConfig (line 52) | default String getRelationConfig(Optional<String> relation, boolean re...

FILE: src/main/java/org/blackdread/sqltojava/view/impl/JdlEntityViewImpl.java
  class JdlEntityViewImpl (line 15) | @Immutable
    method JdlEntityViewImpl (line 34) | public JdlEntityViewImpl(
    method getUndefinedJdlTypeHandling (line 49) | @Override

FILE: src/main/java/org/blackdread/sqltojava/view/impl/JdlFieldViewImpl.java
  class JdlFieldViewImpl (line 13) | @Immutable
    method JdlFieldViewImpl (line 33) | public JdlFieldViewImpl(

FILE: src/main/java/org/blackdread/sqltojava/view/impl/JdlRelationGroupViewImpl.java
  class JdlRelationGroupViewImpl (line 9) | public class JdlRelationGroupViewImpl extends JdlRelationGroupImpl {
    method JdlRelationGroupViewImpl (line 11) | public JdlRelationGroupViewImpl(RelationType relationType, List<JdlRel...

FILE: src/main/java/org/blackdread/sqltojava/view/impl/JdlRelationViewImpl.java
  class JdlRelationViewImpl (line 10) | @Immutable
    method JdlRelationViewImpl (line 30) | public JdlRelationViewImpl(

FILE: src/main/java/org/blackdread/sqltojava/view/mapper/JdlViewMapper.java
  type JdlViewMapper (line 17) | @Mapper(componentModel = "spring", uses = OptionalUtils.class)
    method entityToView (line 19) | JdlEntityViewImpl entityToView(JdlEntityImpl jdlEntity, UndefinedJdlTy...
    method fieldToView (line 20) | JdlFieldViewImpl fieldToView(JdlFieldImpl jdlField);
    method relationToView (line 21) | JdlRelationViewImpl relationToView(JdlRelationImpl jdlRelation);
    method relationToView (line 22) | JdlRelationGroupViewImpl relationToView(JdlRelationGroupImpl jdlRelati...

FILE: src/main/java/org/blackdread/sqltojava/view/mapper/OptionalUtils.java
  class OptionalUtils (line 8) | public class OptionalUtils {
    method OptionalUtils (line 10) | private OptionalUtils() {}
    method fromOptional (line 12) | public static <T> T fromOptional(Optional<T> optional) {

FILE: src/test/java/org/blackdread/sqltojava/AssertUtil.java
  class AssertUtil (line 7) | public final class AssertUtil {
    method assertFileSame (line 9) | public static void assertFileSame(final Collection<String> expected, f...

FILE: src/test/java/org/blackdread/sqltojava/FileUtil.java
  class FileUtil (line 10) | public final class FileUtil {
    method readAllLinesClasspath (line 12) | public static List<String> readAllLinesClasspath(final String name) th...
    method readAllLines (line 16) | public static List<String> readAllLines(final String name) throws URIS...

FILE: src/test/java/org/blackdread/sqltojava/shared/LoggingExtension.java
  class LoggingExtension (line 8) | public class LoggingExtension implements TestInstancePostProcessor {
    method postProcessTestInstance (line 10) | @Override

FILE: src/test/java/org/blackdread/sqltojava/shared/MainApplicationContextLoader.java
  class MainApplicationContextLoader (line 11) | public class MainApplicationContextLoader extends SpringBootContextLoader {
    method getSpringApplication (line 13) | @Override

FILE: src/test/java/org/blackdread/sqltojava/shared/interfaces/CompareJdlResultsTest.java
  type CompareJdlResultsTest (line 10) | public interface CompareJdlResultsTest extends LoggingTest, EnvironmentT...
    method testFileSame (line 11) | @Test

FILE: src/test/java/org/blackdread/sqltojava/shared/interfaces/ContainersStartedTest.java
  type ContainersStartedTest (line 7) | public interface ContainersStartedTest extends JdbcContainerTest {
    method testContainerRunning (line 8) | @Test

FILE: src/test/java/org/blackdread/sqltojava/shared/interfaces/EnvironmentTest.java
  type EnvironmentTest (line 5) | public interface EnvironmentTest {
    method env (line 6) | Environment env();

FILE: src/test/java/org/blackdread/sqltojava/shared/interfaces/JdbcContainerTest.java
  type JdbcContainerTest (line 5) | public interface JdbcContainerTest {
    method container (line 6) | JdbcDatabaseContainer container();
    method container (line 7) | void container(JdbcDatabaseContainer container);

FILE: src/test/java/org/blackdread/sqltojava/shared/interfaces/LoggingTest.java
  type LoggingTest (line 5) | public interface LoggingTest extends JdbcContainerTest {
    method log (line 6) | Logger log();
    method logger (line 7) | void logger(Logger log);

FILE: src/test/java/org/blackdread/sqltojava/shared/interfaces/ProfileActiveTest.java
  type ProfileActiveTest (line 8) | public interface ProfileActiveTest extends EnvironmentTest {
    method testCorrectProfileLoaded (line 9) | @Test

FILE: src/test/java/org/blackdread/sqltojava/shared/tests/BaseJdbcContainerTest.java
  class BaseJdbcContainerTest (line 22) | @Testcontainers
    method setupContainer (line 35) | public static JdbcDatabaseContainer setupContainer(JdbcDatabaseContain...
    method getDefaultSchema (line 50) | private static String getDefaultSchema(JdbcDatabaseContainer c) throws...
    method env (line 65) | @Override
    method log (line 71) | @Override
    method logger (line 76) | @Override
    method container (line 82) | @Override
    method container (line 87) | @Override

FILE: src/test/java/org/blackdread/sqltojava/shared/tests/SqlToJdlTransactionPerTestTest.java
  class SqlToJdlTransactionPerTestTest (line 19) | public abstract class SqlToJdlTransactionPerTestTest extends Transaction...
    method provideTestNames (line 31) | private static Stream<String> provideTestNames() {
    method checkSchemaEmpty (line 53) | @BeforeEach
    method testChangelog (line 65) | @ParameterizedTest
    method testJdl (line 71) | private void testJdl(String testName) {
    method testJdlException (line 87) | protected void testJdlException(String testName, Class<RuntimeExceptio...
    method getExpectedLiquibaseChangeset (line 109) | private String getExpectedLiquibaseChangeset(String testName, String a...
    method getExpectedJdl (line 123) | private String getExpectedJdl(String testName, String activeProfile) {

FILE: src/test/java/org/blackdread/sqltojava/shared/tests/TransactionPerTestTest.java
  class TransactionPerTestTest (line 26) | @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_MET...
    method dataSource (line 44) | public DataSource dataSource() {
    method rollback (line 48) | @AfterEach
    method cleanup (line 56) | @AfterAll
    method pathToString (line 59) | protected String pathToString(String path) {
    method evictAllCaches (line 67) | protected void evictAllCaches() {
    method database (line 72) | private Database database(DataSource dataSource) throws LiquibaseExcep...
    method runChangeLogFile (line 78) | protected void runChangeLogFile(String pathChangeLogFile) throws SQLEx...
    method createLiquibase (line 83) | private Liquibase createLiquibase(String pathChangeLogFile) throws SQL...
    method rollbackToEmpty (line 87) | private void rollbackToEmpty() throws LiquibaseException {

FILE: src/test/java/org/blackdread/sqltojava/test/db/mssql/MssqlSql2019Test.java
  class MssqlSql2019Test (line 14) | @ExtendWith(SystemStubsExtension.class)
    method setEnv (line 26) | protected static void setEnv(String name, String value) {
    method setup (line 30) | @BeforeAll

FILE: src/test/java/org/blackdread/sqltojava/test/db/mysql/MariaDBLatestTest.java
  class MariaDBLatestTest (line 13) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 22) | @BeforeAll

FILE: src/test/java/org/blackdread/sqltojava/test/db/mysql/Mysql57Test.java
  class Mysql57Test (line 13) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 22) | @BeforeAll

FILE: src/test/java/org/blackdread/sqltojava/test/db/mysql/Mysql8Test.java
  class Mysql8Test (line 13) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 22) | @BeforeAll

FILE: src/test/java/org/blackdread/sqltojava/test/db/mysql/Mysql9Test.java
  class Mysql9Test (line 14) | @Disabled("Fails to connect to the container")
    method setup (line 24) | @BeforeAll

FILE: src/test/java/org/blackdread/sqltojava/test/db/mysql/MysqlLatestTest.java
  class MysqlLatestTest (line 14) | @Disabled("Fails to download the container")
    method setup (line 24) | @BeforeAll

FILE: src/test/java/org/blackdread/sqltojava/test/db/oracle/OracleLatestTest.java
  class OracleLatestTest (line 13) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 22) | @BeforeAll

FILE: src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres09Test.java
  class Postgres09Test (line 13) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 24) | @BeforeAll

FILE: src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres10Test.java
  class Postgres10Test (line 13) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 22) | @BeforeAll

FILE: src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres15Test.java
  class Postgres15Test (line 13) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 22) | @BeforeAll

FILE: src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres17Test.java
  class Postgres17Test (line 13) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 22) | @BeforeAll

FILE: src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresAddTableNameJdlTest.java
  class PostgresAddTableNameJdlTest (line 14) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 23) | @BeforeAll
    method provideTestNames (line 30) | private static Stream<String> provideTestNames() {

FILE: src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresDatabaseObjectPrefixTest.java
  class PostgresDatabaseObjectPrefixTest (line 14) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 23) | @BeforeAll
    method provideTestNames (line 29) | private static Stream<String> provideTestNames() {

FILE: src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresLatestTest.java
  class PostgresLatestTest (line 14) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 23) | @BeforeAll
    method provideTestNames_ (line 29) | private static Stream<String> provideTestNames_() {

FILE: src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresOverrideJdlTypeTest.java
  class PostgresOverrideJdlTypeTest (line 15) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 25) | @BeforeAll
    method provideTestNames (line 31) | private static Stream<String> provideTestNames() {

FILE: src/test/java/org/blackdread/sqltojava/test/general/DatabaseObjectPrefixTest.java
  class DatabaseObjectPrefixTest (line 9) | public class DatabaseObjectPrefixTest {
    method testPrefix (line 11) | @Test

FILE: src/test/java/org/blackdread/sqltojava/test/general/MustacheTest.java
  class MustacheTest (line 28) | @ExtendWith(SpringExtension.class)
    class MustacheServiceTestContextConfiguration (line 32) | @TestConfiguration
      method mustacheService (line 35) | @Bean
    method testEntity (line 108) | @Test
    method testRelation (line 124) | @Test
    method testRelationWithoutComments (line 141) | @Test
    method testRelationWithoutBidirectional (line 154) | @Test
    method testEntities (line 167) | @Test
    method testNoEntities (line 191) | @Test
    method testApplication (line 205) | @Test

FILE: src/test/java/org/blackdread/sqltojava/test/general/unsupported/PostgresUndefinedErrorTest.java
  class PostgresUndefinedErrorTest (line 17) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 26) | @BeforeAll
    method testChangelog (line 33) | @ParameterizedTest
    method provideTestNames (line 39) | private static Stream<String> provideTestNames() {

FILE: src/test/java/org/blackdread/sqltojava/test/general/unsupported/PostgresUndefinedSkioTest.java
  class PostgresUndefinedSkioTest (line 15) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 24) | @BeforeAll
    method provideTestNames (line 31) | private static Stream<String> provideTestNames() {

FILE: src/test/java/org/blackdread/sqltojava/test/general/unsupported/PostgresUndefinedUnsupportedTest.java
  class PostgresUndefinedUnsupportedTest (line 15) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 24) | @BeforeAll
    method provideTestNames (line 31) | private static Stream<String> provideTestNames() {

FILE: src/test/java/org/blackdread/sqltojava/test/general/views/PostgresDatabaseObjectTypesTest.java
  class PostgresDatabaseObjectTypesConfigTest (line 15) | @ExtendWith(SystemStubsExtension.class)
    method setup (line 25) | @BeforeAll
    method provideTestNames (line 31) | private static Stream<String> provideTestNames() {
Condensed preview — 203 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (354K chars).
[
  {
    "path": ".editorconfig",
    "chars": 475,
    "preview": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# edit"
  },
  {
    "path": ".gitattributes",
    "chars": 499,
    "preview": "# All text files should have the \"lf\" (Unix) line endings\n* text eol=lf\n\n# Explicitly declare text files you want to alw"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 237,
    "preview": "version: 2\nupdates:\n- package-ecosystem: maven\n  directory: \"/\"\n  schedule:\n    interval: monthly\n  open-pull-requests-l"
  },
  {
    "path": ".github/workflows/maven.yml",
    "chars": 592,
    "preview": "name: Java CI\n\non: [push]\n\njobs:\n    build:\n        runs-on: ubuntu-latest\n        steps:\n            - uses: actions/ch"
  },
  {
    "path": ".gitignore",
    "chars": 1511,
    "preview": "######################\n# Project Specific\n######################\nclasses/artifacts\n/my-project-jdl.jh\n/*.jdl\n/*.jh\n\n####"
  },
  {
    "path": ".mvn/wrapper/maven-wrapper.properties",
    "chars": 97,
    "preview": "distributionUrl=https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.zip\n"
  },
  {
    "path": ".prettierignore",
    "chars": 0,
    "preview": ""
  },
  {
    "path": ".prettierrc",
    "chars": 164,
    "preview": "# Prettier configuration\n\nprintWidth: 140\nsingleQuote: true\ntabWidth: 2\nuseTabs: false\n\n# java rules:\noverrides:\n  - fil"
  },
  {
    "path": ".travis.yml",
    "chars": 323,
    "preview": "language: java\n\n#jdk:\n#  - oraclejdk8\n\ncache:\n    directories:\n        - $HOME/.m2\n\nservices:\n  - mysql\n\nbefore_install:"
  },
  {
    "path": "LICENSE",
    "chars": 1070,
    "preview": "MIT License\n\nCopyright (c) 2018 Yoann CAPLAIN\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
  },
  {
    "path": "README.md",
    "chars": 4131,
    "preview": "[![build](https://github.com/Blackdread/sql-to-jdl/actions/workflows/maven.yml/badge.svg)](https://github.com/Blackdread"
  },
  {
    "path": "checkstyle-suppressions.xml",
    "chars": 349,
    "preview": "<?xml version=\"1.0\"?>\n\n<!DOCTYPE suppressions PUBLIC\n    \"-//Checkstyle//DTD SuppressionFilter Configuration 1.0//EN\"\n  "
  },
  {
    "path": "checkstyle.xml",
    "chars": 5106,
    "preview": "<?xml version=\"1.0\"?>\n<!DOCTYPE module PUBLIC\n    \"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN\"\n    \"https://che"
  },
  {
    "path": "mvnw",
    "chars": 6468,
    "preview": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Softwa"
  },
  {
    "path": "mvnw.cmd",
    "chars": 4994,
    "preview": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software F"
  },
  {
    "path": "pom.xml",
    "chars": 13957,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/SqlToJavaApplication.java",
    "chars": 2045,
    "preview": "package org.blackdread.sqltojava;\n\nimport java.util.List;\nimport org.blackdread.sqltojava.config.ApplicationProperties;\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/config/ApplicationProperties.java",
    "chars": 5491,
    "preview": "package org.blackdread.sqltojava.config;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.P"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/config/CacheConfiguration.java",
    "chars": 505,
    "preview": "package org.blackdread.sqltojava.config;\n\nimport org.springframework.cache.CacheManager;\nimport org.springframework.cach"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/config/DatabaseObjectTypesConfigEnum.java",
    "chars": 120,
    "preview": "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",
    "chars": 1071,
    "preview": "package org.blackdread.sqltojava.config;\n\npublic enum ExportFileStructureType {\n    SEPARATED(\"application\", \"Every enti"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/config/UndefinedJdlTypeHandlingEnum.java",
    "chars": 358,
    "preview": "package org.blackdread.sqltojava.config;\n\n/**\n * Determines how undefined SQL column types ar handled\n */\npublic enum Un"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/JdlEntity.java",
    "chars": 740,
    "preview": "package org.blackdread.sqltojava.entity;\n\nimport java.util.List;\nimport java.util.Optional;\n\npublic interface JdlEntity "
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/JdlField.java",
    "chars": 1176,
    "preview": "package org.blackdread.sqltojava.entity;\n\nimport java.util.Optional;\n\npublic interface JdlField {\n    JdlFieldEnum getTy"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/JdlFieldEnum.java",
    "chars": 1544,
    "preview": "package org.blackdread.sqltojava.entity;\n\nimport com.google.common.base.CaseFormat;\n\npublic enum JdlFieldEnum {\n    STRI"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/JdlRelation.java",
    "chars": 2059,
    "preview": "package org.blackdread.sqltojava.entity;\n\nimport java.util.Optional;\n\npublic interface JdlRelation {\n    RelationType ge"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/JdlRelationGroup.java",
    "chars": 178,
    "preview": "package org.blackdread.sqltojava.entity;\n\nimport java.util.List;\n\npublic interface JdlRelationGroup {\n    RelationType g"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/RelationType.java",
    "chars": 423,
    "preview": "package org.blackdread.sqltojava.entity;\n\npublic enum RelationType {\n    /**\n     * @deprecated no reason to keep that, "
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/SqlColumn.java",
    "chars": 682,
    "preview": "package org.blackdread.sqltojava.entity;\n\nimport java.util.Optional;\n\npublic interface SqlColumn {\n    SqlTable getTable"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/SqlForeignKey.java",
    "chars": 76,
    "preview": "package org.blackdread.sqltojava.entity;\n\npublic interface SqlForeignKey {}\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/SqlTable.java",
    "chars": 206,
    "preview": "package org.blackdread.sqltojava.entity;\n\nimport java.util.Optional;\n\npublic interface SqlTable {\n    String getName();\n"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/JdlEntityImpl.java",
    "chars": 2938,
    "preview": "package org.blackdread.sqltojava.entity.impl;\n\nimport com.google.common.collect.ImmutableList;\nimport java.util.List;\nim"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/JdlFieldImpl.java",
    "chars": 3326,
    "preview": "package org.blackdread.sqltojava.entity.impl;\n\nimport java.util.Optional;\nimport javax.annotation.Nullable;\nimport javax"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/JdlRelationGroupImpl.java",
    "chars": 1392,
    "preview": "package org.blackdread.sqltojava.entity.impl;\n\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.stre"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/JdlRelationImpl.java",
    "chars": 4577,
    "preview": "package org.blackdread.sqltojava.entity.impl;\n\nimport java.util.Optional;\nimport javax.annotation.Nullable;\nimport javax"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/SqlColumnImpl.java",
    "chars": 3640,
    "preview": "package org.blackdread.sqltojava.entity.impl;\n\nimport java.util.Objects;\nimport java.util.Optional;\nimport javax.annotat"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/entity/impl/SqlTableImpl.java",
    "chars": 1750,
    "preview": "package org.blackdread.sqltojava.entity.impl;\n\nimport java.util.Objects;\nimport java.util.Optional;\nimport javax.annotat"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/exporter/ExportFileStructureConfig.java",
    "chars": 1246,
    "preview": "package org.blackdread.sqltojava.exporter;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.blackdread.sqltojava"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/listener/SetDatabaseProfileApplicationEventListener.java",
    "chars": 1310,
    "preview": "package org.blackdread.sqltojava.listener;\n\nimport org.blackdread.sqltojava.util.JdbcUtil;\nimport org.slf4j.Logger;\nimpo"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/parser/SqlParser.java",
    "chars": 610,
    "preview": "package org.blackdread.sqltojava.parser;\n\nimport com.google.common.io.Files;\nimport java.io.File;\n\npublic class SqlParse"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/ColumnInformation.java",
    "chars": 2824,
    "preview": "package org.blackdread.sqltojava.pojo;\n\nimport java.util.Optional;\nimport org.apache.commons.lang3.StringUtils;\n\npublic "
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/TableInformation.java",
    "chars": 1514,
    "preview": "package org.blackdread.sqltojava.pojo;\n\nimport java.util.Objects;\nimport java.util.Optional;\nimport org.apache.commons.l"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/TableRelationInformation.java",
    "chars": 2138,
    "preview": "package org.blackdread.sqltojava.pojo;\n\nimport java.util.Objects;\n\npublic class TableRelationInformation {\n\n    private "
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/rowmaper/ColumnInformationRowMapper.java",
    "chars": 726,
    "preview": "package org.blackdread.sqltojava.pojo.rowmaper;\n\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport org.bla"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/rowmaper/SqlServerColumnInformationRowMapper.java",
    "chars": 715,
    "preview": "package org.blackdread.sqltojava.pojo.rowmaper;\n\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport org.bla"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/rowmaper/SqlServerTableInformationRowMapper.java",
    "chars": 610,
    "preview": "package org.blackdread.sqltojava.pojo.rowmaper;\n\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport org.bla"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/rowmaper/TableInformationRowMapper.java",
    "chars": 603,
    "preview": "package org.blackdread.sqltojava.pojo.rowmaper;\n\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport org.bla"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/pojo/rowmaper/TableRelationInformationRowMapper.java",
    "chars": 661,
    "preview": "package org.blackdread.sqltojava.pojo.rowmaper;\n\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport org.bla"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/repository/InformationSchemaRepository.java",
    "chars": 559,
    "preview": "package org.blackdread.sqltojava.repository;\n\nimport java.util.List;\nimport org.blackdread.sqltojava.pojo.ColumnInformat"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/repository/MsSqlPureSqlInformationSchemaRepository.java",
    "chars": 5088,
    "preview": "package org.blackdread.sqltojava.repository;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io."
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/repository/PureSqlInformationSchemaRepository.java",
    "chars": 4428,
    "preview": "package org.blackdread.sqltojava.repository;\n\nimport java.io.IOException;\nimport java.util.List;\nimport java.util.Map;\ni"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/InformationSchemaService.java",
    "chars": 2260,
    "preview": "package org.blackdread.sqltojava.service;\n\nimport java.util.List;\nimport org.blackdread.sqltojava.config.ApplicationProp"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/MsSqlJdlTypeService.java",
    "chars": 4684,
    "preview": "package org.blackdread.sqltojava.service;\n\nimport static java.util.Map.entry;\nimport static org.blackdread.sqltojava.ent"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/MySqlJdlTypeService.java",
    "chars": 2502,
    "preview": "package org.blackdread.sqltojava.service;\n\nimport static java.util.Map.entry;\nimport static org.blackdread.sqltojava.ent"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/OracleJdlTypeService.java",
    "chars": 1460,
    "preview": "package org.blackdread.sqltojava.service;\n\nimport static java.util.Map.entry;\nimport static org.blackdread.sqltojava.ent"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/PostgresJdlTypeService.java",
    "chars": 2019,
    "preview": "package org.blackdread.sqltojava.service;\n\nimport static java.util.Map.entry;\nimport static org.blackdread.sqltojava.ent"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/SqlJdlTypeService.java",
    "chars": 1321,
    "preview": "package org.blackdread.sqltojava.service;\n\nimport static org.blackdread.sqltojava.entity.JdlFieldEnum.UNSUPPORTED;\n\nimpo"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/logic/ExportService.java",
    "chars": 5553,
    "preview": "package org.blackdread.sqltojava.service.logic;\n\nimport static java.util.Map.entry;\nimport static java.util.Map.ofEntrie"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/logic/JdlService.java",
    "chars": 15557,
    "preview": "package org.blackdread.sqltojava.service.logic;\n\nimport static org.blackdread.sqltojava.entity.JdlFieldEnum.*;\nimport st"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/logic/MustacheService.java",
    "chars": 3338,
    "preview": "package org.blackdread.sqltojava.service.logic;\n\nimport com.github.mustachejava.DefaultMustacheFactory;\nimport com.githu"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/service/logic/SqlService.java",
    "chars": 10344,
    "preview": "package org.blackdread.sqltojava.service.logic;\n\nimport com.google.common.collect.Maps;\nimport java.util.Collection;\nimp"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/AppUtil.java",
    "chars": 702,
    "preview": "package org.blackdread.sqltojava.util;\n\nimport org.blackdread.sqltojava.listener.SetDatabaseProfileApplicationEventListe"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/JdbcUtil.java",
    "chars": 386,
    "preview": "package org.blackdread.sqltojava.util;\n\npublic final class JdbcUtil {\n\n    /**\n     * This method assumes the jdbc url s"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/JdlUtils.java",
    "chars": 1786,
    "preview": "package org.blackdread.sqltojava.util;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.validation.const"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/NamingConventionUtil.java",
    "chars": 1057,
    "preview": "package org.blackdread.sqltojava.util;\n\nimport java.util.Arrays;\nimport java.util.stream.Collectors;\n\npublic final class"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/ResourceUtil.java",
    "chars": 1697,
    "preview": "package org.blackdread.sqltojava.util;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputS"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/util/SqlUtils.java",
    "chars": 3495,
    "preview": "package org.blackdread.sqltojava.util;\n\nimport static com.google.common.base.CaseFormat.LOWER_CAMEL;\nimport static java."
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/JdlCommentView.java",
    "chars": 631,
    "preview": "package org.blackdread.sqltojava.view;\n\nimport java.util.Optional;\n\n/**\n * Methods for comments in the view\n */\npublic i"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/JdlEntityView.java",
    "chars": 2414,
    "preview": "package org.blackdread.sqltojava.view;\n\nimport static org.slf4j.LoggerFactory.getLogger;\n\nimport java.util.List;\nimport "
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/JdlFieldView.java",
    "chars": 3105,
    "preview": "package org.blackdread.sqltojava.view;\n\nimport com.google.common.base.Joiner;\nimport java.util.ArrayList;\nimport java.ut"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/JdlRelationGroupView.java",
    "chars": 198,
    "preview": "package org.blackdread.sqltojava.view;\n\nimport javax.annotation.concurrent.Immutable;\nimport javax.annotation.concurrent"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/JdlRelationView.java",
    "chars": 1677,
    "preview": "package org.blackdread.sqltojava.view;\n\nimport java.util.Optional;\nimport org.blackdread.sqltojava.entity.JdlRelation;\ni"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/impl/JdlEntityViewImpl.java",
    "chars": 1680,
    "preview": "package org.blackdread.sqltojava.view.impl;\n\nimport java.util.List;\nimport javax.annotation.Nullable;\nimport javax.annot"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/impl/JdlFieldViewImpl.java",
    "chars": 1407,
    "preview": "package org.blackdread.sqltojava.view.impl;\n\nimport javax.annotation.Nullable;\nimport javax.annotation.concurrent.Immuta"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/impl/JdlRelationGroupViewImpl.java",
    "chars": 479,
    "preview": "package org.blackdread.sqltojava.view.impl;\n\nimport java.util.List;\nimport java.util.Optional;\nimport org.blackdread.sql"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/impl/JdlRelationViewImpl.java",
    "chars": 1871,
    "preview": "package org.blackdread.sqltojava.view.impl;\n\nimport javax.annotation.Nullable;\nimport javax.annotation.concurrent.Immuta"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/mapper/JdlViewMapper.java",
    "chars": 1117,
    "preview": "package org.blackdread.sqltojava.view.mapper;\n\nimport org.blackdread.sqltojava.config.UndefinedJdlTypeHandlingEnum;\nimpo"
  },
  {
    "path": "src/main/java/org/blackdread/sqltojava/view/mapper/OptionalUtils.java",
    "chars": 294,
    "preview": "package org.blackdread.sqltojava.view.mapper;\n\nimport java.util.Optional;\n\n/**\n * Used to handle Optional with Mapstruct"
  },
  {
    "path": "src/main/resources/application.yml",
    "chars": 1628,
    "preview": "spring:\n    datasource:\n        type: com.zaxxer.hikari.HikariDataSource\n        url: jdbc:mysql://localhost:3306/?useUn"
  },
  {
    "path": "src/main/resources/mustache/application-entities-relations-views.mustache",
    "chars": 143,
    "preview": "{{> entities}}\n\n{{> onetoonerelations}}\n\n{{> manytoonerelations}}\n\n{{> manytomanyrelations}}\n\n{{> views}}\n\n{{> viewsrela"
  },
  {
    "path": "src/main/resources/mustache/application-grouped-relations-separate-views.mustache",
    "chars": 157,
    "preview": "{{> entities}}\n\n{{> groupedonetoonerelations}}\n\n{{> groupedmanytoonerelations}}\n\n{{> manytomanyrelations}}\n\n{{> views}}\n"
  },
  {
    "path": "src/main/resources/mustache/application.mustache",
    "chars": 47,
    "preview": "{{> entities}}\n\n{{> relations}}\n\n{{> options}}\n"
  },
  {
    "path": "src/main/resources/mustache/entities.mustache",
    "chars": 576,
    "preview": "{{#entities}}\n{{^value.isPureManyToMany}}\n{{#value.comment}}\n{{value.docComment}}\n{{/value.comment}}\n{{#value.isReadOnly"
  },
  {
    "path": "src/main/resources/mustache/groupedmanytoonerelations.mustache",
    "chars": 448,
    "preview": "{{#groupedmanytoonerelations}}\n\n{{#first}}// Grouped Relations{{/first}}\n{{#isPureManyToMany}}\n    // TODO This is a pur"
  },
  {
    "path": "src/main/resources/mustache/groupedonetoonerelations.mustache",
    "chars": 896,
    "preview": "{{#groupedonetoonerelations}}\n{{#first}}// Grouped Relations{{/first}}\n{{#isPureManyToMany}}\n    // TODO This is a pure "
  },
  {
    "path": "src/main/resources/mustache/manytomanyrelations.mustache",
    "chars": 860,
    "preview": "{{#manytomanyrelations}}\n{{#first}}// many-to-many Relations{{/first}}\n{{#value.isPureManyToMany}}\n// TODO This is a pur"
  },
  {
    "path": "src/main/resources/mustache/manytoonerelations.mustache",
    "chars": 948,
    "preview": "{{#manytoonerelations}}\n    {{#first}}//many-to-one Relations{{/first}}\n    {{#value.isPureManyToMany}}\n        // TODO "
  },
  {
    "path": "src/main/resources/mustache/onetoonerelations.mustache",
    "chars": 945,
    "preview": "{{#onetoonerelations}}\n    {{#first}}//one-to-one Relations{{/first}}\n    {{#value.isPureManyToMany}}\n        // TODO Th"
  },
  {
    "path": "src/main/resources/mustache/options.mustache",
    "chars": 67,
    "preview": "{{#options}}\n{{#first}}// Options{{/first}}\n{{value}}\n{{/options}}\n"
  },
  {
    "path": "src/main/resources/mustache/relations.mustache",
    "chars": 827,
    "preview": "{{#relations}}\n{{#first}}// Relations{{/first}}\n{{#value.isPureManyToMany}}\n// TODO This is a pure ManyToMany relation ("
  },
  {
    "path": "src/main/resources/mustache/views.mustache",
    "chars": 562,
    "preview": "{{#views}}\n{{^value.isPureManyToMany}}\n{{#value.comment}}\n{{value.docComment}}\n{{/value.comment}}\n{{#value.isReadOnly}}\n"
  },
  {
    "path": "src/main/resources/mustache/viewsrelations.mustache",
    "chars": 837,
    "preview": "{{#viewsrelations}}\n{{#first}}// Relations{{/first}}\n{{#value.isPureManyToMany}}\n// TODO This is a pure ManyToMany relat"
  },
  {
    "path": "src/main/resources/reserved/keywords.json",
    "chars": 2336,
    "preview": "{\n    \"java\": [\n        \"ABSTRACT\",\n        \"CONTINUE\",\n        \"FOR\",\n        \"NEW\",\n        \"SWITCH\",\n        \"ASSERT\""
  },
  {
    "path": "src/main/resources/sql/mysql_mariadb-getAllTableInformation.sql",
    "chars": 592,
    "preview": "select t.table_schema,\n       t.table_name,\n       case\n           when v.is_updatable='NO' then false\n           else t"
  },
  {
    "path": "src/main/resources/sql/mysql_mariadb-getAllTableRelationInformation.sql",
    "chars": 460,
    "preview": "select kku.constraint_name,\n       kku.table_schema,\n       kku.table_name,\n       kku.column_name,\n       kku.reference"
  },
  {
    "path": "src/main/resources/sql/mysql_mariadb-getFullColumnInformationOfTable.sql",
    "chars": 492,
    "preview": "select\n    c.table_schema,\n    c.table_name,\n    c.column_name,\n    case\n        when c.character_maximum_length is null"
  },
  {
    "path": "src/main/resources/sql/oracle-getAllTableInformation.sql",
    "chars": 1161,
    "preview": "select o.OWNER       as schema,\n       o.OBJECT_NAME as table_name,\n       case\n           WHEN v.READ_ONLY = 'Y' THEN '"
  },
  {
    "path": "src/main/resources/sql/oracle-getAllTableRelationInformation.sql",
    "chars": 713,
    "preview": "SELECT a.constraint_name,\n       c.owner              as table_schema,\n       a.table_name,\n       LOWER(a.column_name) "
  },
  {
    "path": "src/main/resources/sql/oracle-getFullColumnInformationOfTable.sql",
    "chars": 2696,
    "preview": "select a.OWNER              as                                                      table_schema,\n       a.TABLE_NAME,\n "
  },
  {
    "path": "src/main/resources/sql/postgresql-getAllTableInformation.sql",
    "chars": 633,
    "preview": "with w_tables as (\n  select t.table_schema,\n         t.table_name,\n         t.is_insertable_into as is_updatable,\n      "
  },
  {
    "path": "src/main/resources/sql/postgresql-getAllTableRelationInformation.sql",
    "chars": 875,
    "preview": "select tc.constraint_name,\n       tc.table_schema,\n       tc.table_name,\n       kcu.column_name,\n       ccu.table_schema"
  },
  {
    "path": "src/main/resources/sql/postgresql-getFullColumnInformationOfTable.sql",
    "chars": 2970,
    "preview": "with w_columns as (\n    select c.table_schema,\n           c.table_name,\n           c.column_name,\n           case\n      "
  },
  {
    "path": "src/main/resources/sql/sqlserver-getAllTableInformation.sql",
    "chars": 757,
    "preview": "WITH w_tables AS (\nSELECT\n    t.TABLE_SCHEMA,\n    t.TABLE_NAME,\n    t.TABLE_TYPE,\n    CASE\n        WHEN t.TABLE_TYPE = '"
  },
  {
    "path": "src/main/resources/sql/sqlserver-getAllTableRelationInformation.sql",
    "chars": 1182,
    "preview": "-- create sqlserver-getAllTableRelationInformation.sql for mssql server database using example file postgresql-getAllTab"
  },
  {
    "path": "src/main/resources/sql/sqlserver-getFullColumnInformationOfTable.sql",
    "chars": 1526,
    "preview": "WITH w_columns AS (\n    SELECT\n        c.TABLE_SCHEMA,\n        c.TABLE_NAME,\n        c.COLUMN_NAME,\n        CASE\n       "
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/AssertUtil.java",
    "chars": 1042,
    "preview": "package org.blackdread.sqltojava;\n\nimport java.util.Collection;\nimport java.util.Iterator;\nimport org.junit.jupiter.api."
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/FileUtil.java",
    "chars": 998,
    "preview": "package org.blackdread.sqltojava;\n\nimport java.io.IOException;\nimport java.net.URISyntaxException;\nimport java.nio.chars"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/LoggingExtension.java",
    "chars": 587,
    "preview": "package org.blackdread.sqltojava.shared;\n\nimport org.blackdread.sqltojava.shared.interfaces.LoggingTest;\nimport org.juni"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/MainApplicationContextLoader.java",
    "chars": 541,
    "preview": "package org.blackdread.sqltojava.shared;\n\nimport org.blackdread.sqltojava.util.AppUtil;\nimport org.springframework.boot."
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/CompareJdlResultsTest.java",
    "chars": 961,
    "preview": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport java.io.IOException;\nimport java.net.URISyntaxException;\nimp"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/ContainersStartedTest.java",
    "chars": 464,
    "preview": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\nimport "
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/EnvironmentTest.java",
    "chars": 163,
    "preview": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport org.springframework.core.env.Environment;\n\npublic interface "
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/JdbcContainerTest.java",
    "chars": 245,
    "preview": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport org.testcontainers.containers.JdbcDatabaseContainer;\n\npublic"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/LoggingTest.java",
    "chars": 185,
    "preview": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport org.slf4j.Logger;\n\npublic interface LoggingTest extends Jdbc"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/interfaces/ProfileActiveTest.java",
    "chars": 699,
    "preview": "package org.blackdread.sqltojava.shared.interfaces;\n\nimport static org.junit.jupiter.api.Assertions.assertNotNull;\n\nimpo"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/tests/BaseJdbcContainerTest.java",
    "chars": 3426,
    "preview": "package org.blackdread.sqltojava.shared.tests;\n\nimport org.blackdread.sqltojava.shared.LoggingExtension;\nimport org.blac"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/tests/SqlToJdlTransactionPerTestTest.java",
    "chars": 4887,
    "preview": "package org.blackdread.sqltojava.shared.tests;\n\nimport static org.assertj.core.api.AssertionsForClassTypes.assertThat;\ni"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/shared/tests/TransactionPerTestTest.java",
    "chars": 3252,
    "preview": "package org.blackdread.sqltojava.shared.tests;\n\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.sql.C"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mssql/MssqlSql2019Test.java",
    "chars": 1250,
    "preview": "package org.blackdread.sqltojava.test.db.mssql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTest"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mysql/MariaDBLatestTest.java",
    "chars": 1028,
    "preview": "package org.blackdread.sqltojava.test.db.mysql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTest"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mysql/Mysql57Test.java",
    "chars": 1003,
    "preview": "package org.blackdread.sqltojava.test.db.mysql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTest"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mysql/Mysql8Test.java",
    "chars": 1002,
    "preview": "package org.blackdread.sqltojava.test.db.mysql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTest"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mysql/Mysql9Test.java",
    "chars": 1086,
    "preview": "package org.blackdread.sqltojava.test.db.mysql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTest"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/mysql/MysqlLatestTest.java",
    "chars": 1094,
    "preview": "package org.blackdread.sqltojava.test.db.mysql;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTest"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/oracle/OracleLatestTest.java",
    "chars": 1029,
    "preview": "package org.blackdread.sqltojava.test.db.oracle;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerTes"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres09Test.java",
    "chars": 1078,
    "preview": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerT"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres10Test.java",
    "chars": 1050,
    "preview": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerT"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres15Test.java",
    "chars": 1050,
    "preview": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerT"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/Postgres17Test.java",
    "chars": 1050,
    "preview": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport org.blackdread.sqltojava.shared.tests.SqlToJdlTransactionPerT"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresAddTableNameJdlTest.java",
    "chars": 1253,
    "preview": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.shar"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresDatabaseObjectPrefixTest.java",
    "chars": 1195,
    "preview": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.shar"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresLatestTest.java",
    "chars": 1186,
    "preview": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.shar"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/db/postgres/PostgresOverrideJdlTypeTest.java",
    "chars": 1343,
    "preview": "package org.blackdread.sqltojava.test.db.postgres;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.shar"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/DatabaseObjectPrefixTest.java",
    "chars": 418,
    "preview": "package org.blackdread.sqltojava.test.general;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.u"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/MustacheTest.java",
    "chars": 7581,
    "preview": "package org.blackdread.sqltojava.test.general;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static "
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/unsupported/PostgresUndefinedErrorTest.java",
    "chars": 1650,
    "preview": "package org.blackdread.sqltojava.test.general.unsupported;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltoj"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/unsupported/PostgresUndefinedSkioTest.java",
    "chars": 1364,
    "preview": "package org.blackdread.sqltojava.test.general.unsupported;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltoj"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/unsupported/PostgresUndefinedUnsupportedTest.java",
    "chars": 1385,
    "preview": "package org.blackdread.sqltojava.test.general.unsupported;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltoj"
  },
  {
    "path": "src/test/java/org/blackdread/sqltojava/test/general/views/PostgresDatabaseObjectTypesTest.java",
    "chars": 1351,
    "preview": "package org.blackdread.sqltojava.test.general.views;\n\nimport java.util.stream.Stream;\nimport org.blackdread.sqltojava.sh"
  },
  {
    "path": "src/test/resources/application.yml",
    "chars": 1724,
    "preview": "spring:\n    datasource:\n        type: com.zaxxer.hikari.HikariDataSource\n        #url: dynamically set based on JdbcData"
  },
  {
    "path": "src/test/resources/container-license-acceptance.txt",
    "chars": 43,
    "preview": "mcr.microsoft.com/mssql/server:2019-latest\n"
  },
  {
    "path": "src/test/resources/db/changelog/db.changelog-master.yaml",
    "chars": 206,
    "preview": "databaseChangeLog:\n    -   changeSet:\n            id: empty\n            author: empty\n            changes:\n             "
  },
  {
    "path": "src/test/resources/jdl/all_jdl_types-expected.jdl",
    "chars": 521,
    "preview": "/** This comment will be taken into account */\nenum EnumType {\n    // But not this one!\n    VALUE1,\n    VALUE2\n}\n\nentity"
  },
  {
    "path": "src/test/resources/jdl/all_types-expected-mariadb.jdl",
    "chars": 1406,
    "preview": "/** my table comment */\nentity AllType {\n    myId String required maxlength(25),\n    myInt Integer required,\n    myIntNu"
  },
  {
    "path": "src/test/resources/jdl/all_types-expected-mysql.jdl",
    "chars": 1404,
    "preview": "/** my table comment */\nentity AllType {\n    myId String required maxlength(25),\n    myInt Integer required,\n    myIntNu"
  },
  {
    "path": "src/test/resources/jdl/all_types-expected-oracle.jdl",
    "chars": 690,
    "preview": "/** my table comment */\nentity OracleType {\n    myId String required maxlength(25),\n    myBoolean Integer,\n    myTinyint"
  },
  {
    "path": "src/test/resources/jdl/all_types-expected-postgresql.jdl",
    "chars": 686,
    "preview": "entity PostgresType {\n    myBoolean Boolean,\n    myDate LocalDate,\n    myTime String minlength(8) maxlength(8) pattern(/"
  },
  {
    "path": "src/test/resources/jdl/all_types-expected-sqlserver.jdl",
    "chars": 1022,
    "preview": "/** my table comment */\nentity AllType {\n    myId String required maxlength(25),\n    myInt Integer required,\n    myIntNu"
  },
  {
    "path": "src/test/resources/jdl/all_types-liquibase-changeset-sqlserver.yaml",
    "chars": 6406,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: all_types-create_table_all\n          author: Generated with liquibase:"
  },
  {
    "path": "src/test/resources/jdl/all_types-liquibase-changeset.yaml",
    "chars": 14658,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: all_types-create_table_all\n          author: Generated with liquibase:"
  },
  {
    "path": "src/test/resources/jdl/display_field_many_to_one-expected-sqlserver.jdl",
    "chars": 272,
    "preview": "entity Player {\n    name String required unique maxlength(255)\n}\n\nentity Team {\n    abrev String required unique maxleng"
  },
  {
    "path": "src/test/resources/jdl/display_field_many_to_one-expected.jdl",
    "chars": 446,
    "preview": "entity Player {\n    /** Used as display field because it is the first unique not foreign key column */\n    name String r"
  },
  {
    "path": "src/test/resources/jdl/display_field_many_to_one-liquibase-changeset.yaml",
    "chars": 2731,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: create_table_team-1\n          author: jason.long\n          changes:\n  "
  },
  {
    "path": "src/test/resources/jdl/duplicate_names-expected.jdl",
    "chars": 611,
    "preview": "entity Task {\n    name String required maxlength(255),\n    summary String maxlength(255),\n    description String maxleng"
  },
  {
    "path": "src/test/resources/jdl/duplicate_names-liquibase-changeset.yaml",
    "chars": 3660,
    "preview": "databaseChangeLog:\n- changeSet:\n    id: 1674449168689-1\n    author: Generated with liquibase:generate-changelog from mav"
  },
  {
    "path": "src/test/resources/jdl/enum-expected-sqlserver.jdl",
    "chars": 233,
    "preview": "entity City {\n    id String required maxlength(25),\n    name String maxlength(45),\n    /** city_status comment */\n    ci"
  },
  {
    "path": "src/test/resources/jdl/enum-expected.jdl",
    "chars": 253,
    "preview": "entity City {\n    id String required maxlength(25),\n    name String maxlength(45),\n    /** city_status comment */\n    ci"
  },
  {
    "path": "src/test/resources/jdl/enum-liquibase-changeset-sqlserver.yaml",
    "chars": 3415,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: enum-create-table-city\n          author: Generated with liquibase:gene"
  },
  {
    "path": "src/test/resources/jdl/enum-liquibase-changeset.yaml",
    "chars": 4456,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: enum-create-table-city\n          author: Generated with liquibase:gene"
  },
  {
    "path": "src/test/resources/jdl/many_to_one-expected.jdl",
    "chars": 498,
    "preview": "/** many_to_one_child comment */\nentity ManyToOneChild {\n    id String required maxlength(25),\n    name String required "
  },
  {
    "path": "src/test/resources/jdl/many_to_one-liquibase-changeset.yaml",
    "chars": 3415,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: many_to_one-1\n          author: Generated with liquibase:generate-chan"
  },
  {
    "path": "src/test/resources/jdl/one_to_one-expected.jdl",
    "chars": 456,
    "preview": "entity OneToOneChild {\n    id String required maxlength(25),\n    name String required maxlength(45),\n    other String re"
  },
  {
    "path": "src/test/resources/jdl/one_to_one-liquibase-changeset.yaml",
    "chars": 2962,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: one_to_one-1\n          author: Generated with liquibase:generate-chang"
  },
  {
    "path": "src/test/resources/jdl/one_to_one_main_map-expected.jdl",
    "chars": 373,
    "preview": "entity OneToOneChildMap {\n    name String required maxlength(45)\n}\n\n/** one_to_one_main_map comment */\nentity OneToOneMa"
  },
  {
    "path": "src/test/resources/jdl/one_to_one_main_map-liquibase-changeset.yaml",
    "chars": 2546,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: one_to_one_main_map-1\n          author: Generated with liquibase:gener"
  },
  {
    "path": "src/test/resources/jdl/override_jdl_types-expected-postgresql.jdl",
    "chars": 135,
    "preview": "entity Override {\n    /** This column should be overridden to JDL type Float from the default of BigDecimal. */\n    f Fl"
  },
  {
    "path": "src/test/resources/jdl/override_jdl_types-liquibase-changeset.yaml",
    "chars": 819,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: override_jdl_types-create_table\n          author: jason.long\n         "
  },
  {
    "path": "src/test/resources/jdl/parent_child-expected.jdl",
    "chars": 675,
    "preview": "entity Child {\n    id String required maxlength(25),\n    name String required maxlength(45),\n    other String required m"
  },
  {
    "path": "src/test/resources/jdl/parent_child-liquibase-changeset.yaml",
    "chars": 4931,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: parent_child-1\n          author: Generated with liquibase:generate-cha"
  },
  {
    "path": "src/test/resources/jdl/prefix-expected.jdl",
    "chars": 422,
    "preview": "/** many_to_one_child comment */\nentity ManyToOneChild {\n    name String required maxlength(45),\n    other String requir"
  },
  {
    "path": "src/test/resources/jdl/prefix-liquibase-changeset.yaml",
    "chars": 3348,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: many_to_one_prefix-1\n          author: jason.long\n          changes:\n "
  },
  {
    "path": "src/test/resources/jdl/prune-expected.jdl",
    "chars": 16,
    "preview": "entity Demo {\n}\n"
  },
  {
    "path": "src/test/resources/jdl/prune-liquibase-changeset.yaml",
    "chars": 1711,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: prune-1\n          author: Generated with liquibase:generate-changelog "
  },
  {
    "path": "src/test/resources/jdl/readonly-expected-sqlserver.jdl",
    "chars": 231,
    "preview": "/** view */\n@readOnly\nentity Nonupdatable {\n    id Long required,\n    num Integer required\n}\n\nentity TestTable {\n    num"
  },
  {
    "path": "src/test/resources/jdl/readonly-expected.jdl",
    "chars": 221,
    "preview": "/** view */\n@readOnly\nentity Nonupdatable {\n    id Long required,\n    num Integer required\n}\n\nentity TestTable {\n    num"
  },
  {
    "path": "src/test/resources/jdl/readonly-liquibase-changeset.yaml",
    "chars": 1647,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: view-create-table\n          author: jason.long\n          changes:\n    "
  },
  {
    "path": "src/test/resources/jdl/reflexive_relationship-expected.jdl",
    "chars": 186,
    "preview": "entity Invoice {\n    num String required unique maxlength(10),\n    amount BigDecimal required\n}\n\n// Relations\nrelationsh"
  },
  {
    "path": "src/test/resources/jdl/reflexive_relationship-liquibase-changeset.yaml",
    "chars": 1647,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: create_table_invoices-1\n          author: jason.long\n          changes"
  },
  {
    "path": "src/test/resources/jdl/table_name-expected.jdl",
    "chars": 30,
    "preview": "entity T(t) {\n    f Integer\n}\n"
  },
  {
    "path": "src/test/resources/jdl/table_name-liquibase-changeset.yaml",
    "chars": 574,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: table_name-1\n          author: jason.long\n          changes:\n         "
  },
  {
    "path": "src/test/resources/jdl/tables-only-expected.jdl",
    "chars": 46,
    "preview": "entity TestTable {\n    num Integer required\n}\n"
  },
  {
    "path": "src/test/resources/jdl/tables-only-liquibase-changeset.yaml",
    "chars": 1256,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: view-create-table\n          author: jason.long\n          changes:\n    "
  },
  {
    "path": "src/test/resources/jdl/undefined_error-expected.jdl",
    "chars": 11,
    "preview": "//Place hol"
  },
  {
    "path": "src/test/resources/jdl/undefined_error-liquibase-changeset.yaml",
    "chars": 745,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: undefined_unsupported-1\n          author: jason.long\n          changes"
  },
  {
    "path": "src/test/resources/jdl/undefined_skip-expected.jdl",
    "chars": 54,
    "preview": "entity UndefinedUnsupported {\n    supported Integer\n}\n"
  },
  {
    "path": "src/test/resources/jdl/undefined_skip-liquibase-changeset.yaml",
    "chars": 745,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: undefined_unsupported-1\n          author: jason.long\n          changes"
  },
  {
    "path": "src/test/resources/jdl/undefined_unsupported-expected.jdl",
    "chars": 101,
    "preview": "entity UndefinedUnsupported {\n    supported Integer,\n    /**  ARRAY */\n    unsupported Unsupported\n}\n"
  },
  {
    "path": "src/test/resources/jdl/undefined_unsupported-liquibase-changeset.yaml",
    "chars": 745,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: undefined_unsupported-1\n          author: jason.long\n          changes"
  },
  {
    "path": "src/test/resources/jdl/unique-expected-oracle.jdl",
    "chars": 96,
    "preview": "entity Student {\n    id Integer required,\n    ssnnumber String required unique maxlength(100)\n}\n"
  },
  {
    "path": "src/test/resources/jdl/unique-expected-sqlserver.jdl",
    "chars": 96,
    "preview": "entity Student {\n    id Integer required,\n    ssnNumber String required unique maxlength(100)\n}\n"
  },
  {
    "path": "src/test/resources/jdl/unique-expected.jdl",
    "chars": 96,
    "preview": "entity Student {\n    id Integer required,\n    ssnNumber String required unique maxlength(100)\n}\n"
  },
  {
    "path": "src/test/resources/jdl/unique-liquibase-changeset.yaml",
    "chars": 555,
    "preview": "databaseChangeLog:\n- changeSet:\n    id: unique-1\n    author: Generated with liquibase:generate-changelog from flyway sql"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-expected-mariadb.jdl",
    "chars": 63,
    "preview": "entity UuidIdRequired {\n    id String required maxlength(36)\n}\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-expected-mysql.jdl",
    "chars": 63,
    "preview": "entity UuidIdRequired {\n    id String required maxlength(36)\n}\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-expected-postgresql.jdl",
    "chars": 38,
    "preview": "entity UuidIdRequired {\n    id UUID\n}\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-expected-sqlserver.jdl",
    "chars": 38,
    "preview": "entity UuidIdRequired {\n    id UUID\n}\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-expected.jdl",
    "chars": 38,
    "preview": "entity UuidIdRequired {\n    id UUID\n}\n"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-liquibase-changeset-sqlserver.yaml",
    "chars": 518,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: uuid_id_required\n          author: jason.long\n          #dbms: sqlserv"
  },
  {
    "path": "src/test/resources/jdl/uuid_id_required-liquibase-changeset.yaml",
    "chars": 510,
    "preview": "databaseChangeLog:\n    - changeSet:\n          id: uuid_id_required\n          author: jason.long\n          #dbms: mysql,m"
  },
  {
    "path": "src/test/resources/jdl/views-expected.jdl",
    "chars": 307,
    "preview": "entity OrderDetails {\n    orderNumber String required maxlength(255),\n    productCode String required maxlength(50),\n   "
  }
]

// ... and 3 more files (download for full content)

About this extraction

This page contains the full source code of the Blackdread/sql-to-jdl GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 203 files (316.5 KB), approximately 74.3k tokens, and a symbol index with 492 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!