• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

database-rider / database-rider / #913

07 Nov 2025 08:48PM UTC coverage: 84.036% (+0.009%) from 84.027%
#913

push

web-flow
fix: ERROR log with NPE on DataSetExporter#export using includeTables (#593)

11 of 13 new or added lines in 1 file covered. (84.62%)

3090 of 3677 relevant lines covered (84.04%)

0.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.51
/rider-core/src/main/java/com/github/database/rider/core/exporter/DataSetExporter.java
1
package com.github.database.rider.core.exporter;
2

3
import com.github.database.rider.core.api.exporter.BuilderType;
4
import com.github.database.rider.core.api.exporter.DataSetExportConfig;
5
import com.github.database.rider.core.dataset.writer.JSONWriter;
6
import com.github.database.rider.core.dataset.writer.YMLWriter;
7
import com.github.database.rider.core.exporter.builder.BuilderExportConfig;
8
import com.github.database.rider.core.exporter.builder.DataSetBuilderExporter;
9
import org.dbunit.DatabaseUnitException;
10
import org.dbunit.database.*;
11
import org.dbunit.database.search.TablesDependencyHelper;
12
import org.dbunit.dataset.IDataSet;
13
import org.dbunit.dataset.csv.CsvDataSetWriter;
14
import org.dbunit.dataset.excel.XlsDataSetWriter;
15
import org.dbunit.dataset.xml.FlatDtdDataSet;
16
import org.dbunit.dataset.xml.FlatXmlDataSet;
17
import org.slf4j.Logger;
18
import org.slf4j.LoggerFactory;
19

20
import java.io.File;
21
import java.io.FileOutputStream;
22
import java.io.IOException;
23
import java.io.OutputStream;
24
import java.nio.file.Paths;
25
import java.sql.Connection;
26
import java.sql.SQLException;
27
import java.util.Arrays;
28
import java.util.LinkedHashSet;
29
import java.util.Set;
30
import java.util.regex.Matcher;
31
import java.util.regex.Pattern;
32

33
/**
34
 * Created by pestano on 09/09/16.
35
 *
36
 * based on: http://archive.oreilly.com/pub/post/dbunit_made_easy.html
37
 */
38
public class DataSetExporter {
39

40
    /**
41
     * A regular expression that is used to get the table name
42
     * from a SQL 'select' statement.
43
     * This  pattern matches a string that starts with any characters,
44
     * followed by the case-insensitive word 'from',
45
     * followed by a table name of the form 'foo' or 'schema.foo',
46
     * followed by any number of remaining characters.
47
     */
48
    private static final Pattern TABLE_MATCH_PATTERN = Pattern.compile(".*\\s+from\\s+(\\w+(\\.\\w+)?).*",
1✔
49
            Pattern.CASE_INSENSITIVE);
50

51
    private static Logger log = LoggerFactory.getLogger(DataSetExporter.class.getName());
1✔
52

53

54
    private static DataSetExporter instance;
55

56
    private DataSetExporter() {
57
    }
58

59
    public static DataSetExporter getInstance() {
60
        if (instance == null) {
1✔
61
            instance = new DataSetExporter();
1✔
62
        }
63
        return instance;
1✔
64
    }
65

66
    public OutputStream export(Connection connection, DataSetExportConfig dataSetExportConfig) throws SQLException, DatabaseUnitException {
67
        return export(connection, dataSetExportConfig, null);
1✔
68
    }
69

70
    public OutputStream export(Connection connection, DataSetExportConfig dataSetExportConfig, String schema) throws SQLException, DatabaseUnitException {
71
        return export(new DatabaseConnection(connection, schema), dataSetExportConfig);
1✔
72
    }
73

74
    public OutputStream export(DatabaseConnection databaseConnection, DataSetExportConfig dataSetExportConfig) throws SQLException, DatabaseUnitException {
75

76
        if (databaseConnection == null || databaseConnection.getConnection() == null || databaseConnection.getConnection().isClosed()) {
1✔
77
            throw new RuntimeException("Provide a valid connection to export datasets");
×
78
        }
79

80
        if (dataSetExportConfig == null) {
1✔
81
            dataSetExportConfig = new DataSetExportConfig();
×
82
        }
83

84
        String outputFile = dataSetExportConfig.getOutputFileName();
1✔
85

86
        if (outputFile == null || "".equals(outputFile)) {
1✔
87
            throw new RuntimeException("Provide output file name to export dataset.");
×
88
        }
89

90
        if (!outputFile.contains(".")) {
1✔
91
            outputFile = outputFile + "." + dataSetExportConfig.getDataSetFormat().name().toLowerCase();
1✔
92
        }
93

94
        if (outputFile.contains("/") && System.getProperty("os.name").toLowerCase().contains("win")) {
1✔
95
            outputFile = outputFile.replace("/", "\\");
×
96
        }
97

98
        boolean hasIncludes = dataSetExportConfig.getIncludeTables() != null && dataSetExportConfig.getIncludeTables().length > 0;
1✔
99

100

101
        DatabaseConfig config = databaseConnection.getConfig();
1✔
102
        config.setProperty(DatabaseConfig.PROPERTY_RESULTSET_TABLE_FACTORY, new ForwardOnlyResultSetTableFactory());
1✔
103

104
        Set <String> targetTables = new LinkedHashSet<>();
1✔
105

106
        if (hasIncludes) {
1✔
107
            targetTables.addAll(Arrays.asList(dataSetExportConfig.getIncludeTables()));
1✔
108
            if (dataSetExportConfig.isDependentTables()) {
1✔
109
                String[] dependentTables = TablesDependencyHelper.getAllDependentTables(databaseConnection, dataSetExportConfig.getIncludeTables());
1✔
110
                if (dependentTables != null && dependentTables.length > 0) {
1✔
111
                    targetTables.addAll(Arrays.asList(dependentTables));
1✔
112
                }
113
            }
114
        }
115

116
        IDataSet dataSet = new QueryDataSet(databaseConnection);
1✔
117
        if ((!targetTables.isEmpty()) || (dataSetExportConfig.getQueryList() != null && dataSetExportConfig.getQueryList().length > 0)) {
1✔
118
            addQueries((QueryDataSet) dataSet, dataSetExportConfig.getQueryList(), targetTables);
1✔
119
        } else {
120
            dataSet = databaseConnection.createDataSet();
1✔
121
        }
122

123
        FileOutputStream fos = null;
1✔
124
        FileOutputStream fosDtd = null;
1✔
125
        try {
126
            if (outputFile.contains(System.getProperty("file.separator"))) {
1✔
127
                String pathWithoutFileName = outputFile.substring(0, outputFile.lastIndexOf(System.getProperty("file.separator")) + 1);
1✔
128
                new File(pathWithoutFileName).mkdirs();
1✔
129
            }
130
            fos = new FileOutputStream(outputFile);
1✔
131
            switch (dataSetExportConfig.getDataSetFormat()) {
1✔
132
                case XML_DTD: {
133
                    FlatXmlDataSet.write(dataSet, fos);
1✔
134
                    //dtd file has the same name but other file extension
135
                    fosDtd = new FileOutputStream(outputFile.substring(0, outputFile.lastIndexOf('.')) + ".dtd");
1✔
136
                    FlatDtdDataSet.write(dataSet, fosDtd);
1✔
137
                    break;
1✔
138
                }
139
                case XML: {
140
                    FlatXmlDataSet.write(dataSet, fos);
1✔
141
                    break;
1✔
142
                }
143
                case YML: {
144
                    new YMLWriter(fos).write(dataSet);
1✔
145
                    break;
1✔
146
                }
147
                case XLS: {
148
                    config.setProperty(DatabaseConfig.PROPERTY_RESULTSET_TABLE_FACTORY, new CachedResultSetTableFactory());
1✔
149
                    new XlsDataSetWriter().write(dataSet, fos);
1✔
150
                    break;
1✔
151
                }
152
                case XLSX: {
153
                    config.setProperty(DatabaseConfig.PROPERTY_RESULTSET_TABLE_FACTORY, new CachedResultSetTableFactory());
1✔
154
                    new XlsxDataSetWriter().write(dataSet, fos);
1✔
155
                    break;
1✔
156
                }
157
                case CSV: {
158
                    //csv needs a directory instead of file
159
                    outputFile = outputFile.substring(0, outputFile.lastIndexOf('.'));
1✔
160
                    CsvDataSetWriter.write(dataSet, new File(outputFile));
1✔
161
                    break;
1✔
162
                }
163
                case JSON: {
164
                    config.setProperty(DatabaseConfig.PROPERTY_RESULTSET_TABLE_FACTORY, new CachedResultSetTableFactory());
1✔
165
                    new JSONWriter(fos, dataSet).write();
1✔
166
                    break;
1✔
167
                }
168
                default: {
169
                    throw new RuntimeException("Format not supported.");
×
170
                }
171
            }
172
            log.info("DataSet exported successfully at " + Paths.get(outputFile).toAbsolutePath().toString());
1✔
173

174
            boolean generateBuilder = BuilderType.NONE != dataSetExportConfig.getBuilderType();
1✔
175
            if(generateBuilder) {
1✔
176
                String builderName = outputFile.substring(0, outputFile.lastIndexOf('.'))+".java";
1✔
177
                new DataSetBuilderExporter().export(dataSet, new BuilderExportConfig(dataSetExportConfig.getBuilderType(), new File(builderName)));
1✔
178
            }
179
        } catch (Exception e) {
×
180
            log.error("Could not export dataset.", e);
×
181
            throw new RuntimeException("Could not export dataset.", e);
×
182
        } finally {
183
            if (fos != null) {
1✔
184
                try {
185
                    fos.close();
1✔
186
                } catch (IOException e) {
×
187
                    log.error("Could not close file output stream.", e);
×
188
                }
1✔
189
            }
190
            if (fosDtd != null) {
1✔
191
                try {
192
                    fosDtd.close();
1✔
193
                } catch (IOException e) {
×
194
                    log.error("Could not close file output stream for dtd file.", e);
×
195
                }
1✔
196
            }
197
            //set back default ResultSetTableFactory
198
            config.setProperty(DatabaseConfig.PROPERTY_RESULTSET_TABLE_FACTORY, new CachedResultSetTableFactory());
1✔
199

200
        }
201

202
        return null;
1✔
203
    }
204

205
    private void addQueries(QueryDataSet dataSet, String[] queryList, Set<String> targetTables) {
206
        try {
207
            if (targetTables != null) {
1✔
208
                for (String targetTable : targetTables) {
1✔
209
                    dataSet.addTable(targetTable);
1✔
210
                }
1✔
211
            }
212
            if (queryList != null) {
1✔
213
                for (String query : queryList) {
1✔
214
                    //gets the first select to extract table
215
                    Matcher m = TABLE_MATCH_PATTERN.matcher(query.split("(?i)select")[1]);
1✔
216
                    if (!m.matches()) {
1✔
NEW
217
                        log.warn("Unable to parse query. Ignoring '" + query + "'.");
×
218
                    } else {
219
                        String table = m.group(1);
1✔
220
                        if (targetTables.contains(table)) {
1✔
221
                            //already in includes
NEW
222
                            log.warn(String.format("Ignoring query %s because its table is already in includedTables.", query));
×
223
                        } else {
224
                            dataSet.addTable(table, query);
1✔
225
                        }
226
                    }
227
                }
228
            }
229
        } catch (Exception e) {
×
230
            log.error("Could not add query due to following error.", e);
×
231
        }
1✔
232

233
    }
1✔
234
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc