Skip to content

Commit

Permalink
[#6261] Support loading multiple files in DDLDatabase
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaseder committed Jan 18, 2018
1 parent 7a2775a commit 308311a
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 59 deletions.
9 changes: 8 additions & 1 deletion jOOQ-manual/src/main/resources/org/jooq/web/manual-3.11.xml
Expand Up @@ -17976,7 +17976,14 @@ CREATE TABLE book_to_book_store (
<name>org.jooq.util.ddl.DDLDatabase</name>
<properties>

<!-- Specify the location of your SQL script. Future versions may also support more than one script, or directories -->
<!-- Specify the location of your SQL script.
You may use ant-style file matching, e.g. /path/**/to/*.sql

Where:
- ** matches any directory subtree
- * matches any number of characters in a directory / file name
- ? matches a single character in a directory / file name
-->
<property>
<key>scripts</key>
<value>src/main/resources/database.sql</value>
Expand Down
146 changes: 88 additions & 58 deletions jOOQ-meta-extensions/src/main/java/org/jooq/util/ddl/DDLDatabase.java
Expand Up @@ -42,6 +42,7 @@

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
Expand Down Expand Up @@ -106,83 +107,112 @@ protected DSLContext create0() {
ctx = DSL.using(connection);

InputStream in = null;
try {
in = DDLDatabase.class.getResourceAsStream(scripts);
if (in != null) {
log.info("Reading from classpath: " + scripts);
boolean loaded = false;
in = DDLDatabase.class.getResourceAsStream(scripts);
if (in != null) {
log.info("Reading from classpath: " + scripts);
load(encoding, in);
loaded = true;
}
else {
File file = new File(scripts);

if (file.exists()) {
load(encoding, file, null);
loaded = true;
}
else {
File file = new File(scripts);
else if (scripts.contains("*") || scripts.contains("?")) {
file = new File(scripts.replaceAll("[*?].*", ""));

if (file.exists()) {
if (file.isFile()) {
log.info("Reading from file: " + scripts);
in = new FileInputStream(file);
}
else if (file.isDirectory()) {
log.warn("Reading from directory not yet supported: " + scripts);
}
Pattern pattern = Pattern.compile(scripts
.replace("\\", "/")
.replace(".", "\\.")
.replace("?", ".")
.replace("**", ".+?")
.replace("*", "[^/]*")
);

load(encoding, file, pattern);
loaded = true;
}
}
}

if (in != null) {
Scanner s = new Scanner(in, encoding).useDelimiter("\\A");
Queries queries = ctx.parser().parse(s.hasNext() ? s.next() : "");
if (!loaded)
log.error("Could not find script source : " + scripts);
}
catch (ParserException e) {
log.error("An exception occurred while parsing script source : " + scripts + ". Please report this error to https://github.com/jOOQ/jOOQ/issues/new", e);
throw e;
}
catch (Exception e) {
throw new DataAccessException("Error while exporting schema", e);
}
}

return ctx;
}

for (Query query : queries) {
private void load(String encoding, File file, Pattern pattern) throws IOException {
if (file.isFile()) {
if (pattern == null || pattern.matcher(file.getCanonicalPath().replace("\\", "/")).matches()) {
log.info("Reading from: " + file + " [*]");
load(encoding, new FileInputStream(file));
}
}
else if (file.isDirectory()) {
log.info("Reading from: " + file);

repeat:
for (;;) {
try {
query.execute();
log.info(query);
break repeat;
}
catch (DataAccessException e) {
for (File f : file.listFiles())
load(encoding, f, pattern);
}
}

private void load(String encoding, InputStream in) {
try {
Scanner s = new Scanner(in, encoding).useDelimiter("\\A");
Queries queries = ctx.parser().parse(s.hasNext() ? s.next() : "");

// [#7039] Auto create missing schemas. We're using the
if (Integer.toString(ErrorCode.SCHEMA_NOT_FOUND_1).equals(e.sqlState())) {
SQLException cause = e.getCause(SQLException.class);
for (Query query : queries) {

if (cause != null) {
Matcher m = P_NAME.matcher(cause.getMessage());
repeat:
for (;;) {
try {
query.execute();
log.info(query);
break repeat;
}
catch (DataAccessException e) {

// [#7039] Auto create missing schemas. We're using the
if (Integer.toString(ErrorCode.SCHEMA_NOT_FOUND_1).equals(e.sqlState())) {
SQLException cause = e.getCause(SQLException.class);

if (m.find()) {
Query createSchema = ctx.createSchemaIfNotExists(name(m.group(1)));
createSchema.execute();
log.info(createSchema);
continue repeat;
}
}
}
if (cause != null) {
Matcher m = P_NAME.matcher(cause.getMessage());

throw e;
if (m.find()) {
Query createSchema = ctx.createSchemaIfNotExists(name(m.group(1)));
createSchema.execute();
log.info(createSchema);
continue repeat;
}
}
}

throw e;
}
else {
log.error("Could not find script source : " + scripts);
}
}
finally {
if (in != null)
try {
in.close();
}
catch (Exception ignore) {}
}
}
catch (ParserException e) {
log.error("An exception occurred while parsing script source : " + scripts + ". Please report this error to https://github.com/jOOQ/jOOQ/issues/new", e);
throw e;
}
catch (Exception e) {
throw new DataAccessException("Error while exporting schema", e);
}
}

return ctx;
finally {
if (in != null)
try {
in.close();
}
catch (Exception ignore) {}
}
}

@Override
Expand Down

0 comments on commit 308311a

Please sign in to comment.