Skip to content

Commit 7201a8c

Browse files
committed
Merge branch 'DBTOOLS-1694-analyzer' into 'master'
DatabaseFactory refactoring See merge request codekeeper/pgcodekeeper-core!47
2 parents a06ac77 + 3448676 commit 7201a8c

File tree

2 files changed

+93
-60
lines changed

2 files changed

+93
-60
lines changed

src/main/java/org/pgcodekeeper/core/api/DatabaseFactory.java

Lines changed: 61 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@
1616
package org.pgcodekeeper.core.api;
1717

1818
import org.pgcodekeeper.core.PgCodekeeperException;
19-
import org.pgcodekeeper.core.loader.DatabaseLoader;
20-
import org.pgcodekeeper.core.loader.LoaderFactory;
21-
import org.pgcodekeeper.core.loader.PgDumpLoader;
22-
import org.pgcodekeeper.core.loader.ProjectLoader;
19+
import org.pgcodekeeper.core.loader.*;
2320
import org.pgcodekeeper.core.localizations.Messages;
2421
import org.pgcodekeeper.core.model.difftree.IIgnoreList;
2522
import org.pgcodekeeper.core.model.difftree.IgnoreSchemaList;
@@ -37,40 +34,75 @@
3734
/**
3835
* Factory class for loading database schemas from various sources.
3936
* <p>
40-
* This class provides static methods to create {@link AbstractDatabase} instances
37+
* This class provides methods to create {@link AbstractDatabase} instances
4138
* from different sources: JDBC connections, project directories, and database dumps.
4239
* Some loading method supports optional schema filtering through ignore lists.
4340
* </p>
4441
*/
4542
public final class DatabaseFactory {
4643

44+
private final ISettings settings;
45+
private final boolean ignoreErrors;
46+
private final boolean needAnalyze;
47+
private final IMonitor monitor;
48+
4749
/**
48-
* Loads database from a JDBC connection.
50+
* Constructor with default arguments
51+
*
52+
* @param settings configuration settings
53+
*/
54+
public DatabaseFactory(ISettings settings) {
55+
this(settings, false, true);
56+
}
57+
58+
/**
59+
* Constructor with default progress monitor
4960
*
50-
* @param settings ISettings object
61+
* @param settings configuration settings
62+
* @param ignoreErrors behavior on parsing errors
63+
* @param needAnalyze if true, then after loading all database objects, an analysis will be run to find dependencies
64+
*/
65+
public DatabaseFactory(ISettings settings, boolean ignoreErrors, boolean needAnalyze) {
66+
this(settings, ignoreErrors, needAnalyze, new NullMonitor());
67+
}
68+
69+
/**
70+
* @param settings configuration settings
71+
* @param ignoreErrors behavior on parsing errors
72+
* @param needAnalyze if true, then after loading all database objects, an analysis will be run to find dependencies
73+
* @param monitor progress monitor for tracking the operation
74+
*/
75+
public DatabaseFactory(ISettings settings, boolean ignoreErrors, boolean needAnalyze, IMonitor monitor) {
76+
this.settings = settings;
77+
this.ignoreErrors = ignoreErrors;
78+
this.needAnalyze = needAnalyze;
79+
this.monitor = monitor;
80+
}
81+
82+
/**
83+
* Loads database from a JDBC connection.
5184
* @param url the JDBC connection URL
5285
* @return the loaded database
5386
* @throws IOException if I/O operations fail
54-
* @throws PgCodekeeperException if database loading is interrupted or parsing errors occur
87+
* @throws PgCodekeeperException if parsing errors occur
88+
* @throws InterruptedException if operation is cancelled
5589
*/
56-
public static AbstractDatabase loadFromJdbc(ISettings settings, String url)
90+
public AbstractDatabase loadFromJdbc(String url)
5791
throws IOException, PgCodekeeperException, InterruptedException {
58-
return loadFromJdbc(settings, url, null, new NullMonitor());
92+
return loadFromJdbc(url, null);
5993
}
6094

6195
/**
6296
* Loads database from a JDBC connection with schema filtering and monitoring.
6397
*
64-
* @param settings ISettings object
6598
* @param url the JDBC connection URL
6699
* @param ignoreSchemaListPath path to file containing schemas to ignore, or null for no filtering
67-
* @param monitor progress monitor for tracking the operation
68100
* @return the loaded database
69101
* @throws IOException if I/O operations fail
70-
* @throws PgCodekeeperException if database loading is interrupted or parsing errors occur
102+
* @throws PgCodekeeperException if parsing errors occur
103+
* @throws InterruptedException if operation is cancelled
71104
*/
72-
public static AbstractDatabase loadFromJdbc(ISettings settings, String url, String ignoreSchemaListPath,
73-
IMonitor monitor)
105+
public AbstractDatabase loadFromJdbc(String url, String ignoreSchemaListPath)
74106
throws IOException, PgCodekeeperException, InterruptedException {
75107
var ignoreSchemaList = IIgnoreList.parseIgnoreList(ignoreSchemaListPath, new IgnoreSchemaList());
76108
var loader = LoaderFactory.createJdbcLoader(settings, url, ignoreSchemaList, monitor);
@@ -80,30 +112,28 @@ public static AbstractDatabase loadFromJdbc(ISettings settings, String url, Stri
80112
/**
81113
* Loads database from a project directory with schema filtering.
82114
*
83-
* @param settings ISettings object
84115
* @param projectPath path to the project directory containing SQL files
85116
* @return the loaded database
86-
* @throws PgCodekeeperException if database loading is interrupted or parsing errors occur
117+
* @throws PgCodekeeperException if parsing errors occur
87118
* @throws IOException if I/O operations fail
119+
* @throws InterruptedException if operation is cancelled
88120
*/
89-
public static AbstractDatabase loadFromProject(ISettings settings, String projectPath)
121+
public AbstractDatabase loadFromProject(String projectPath)
90122
throws PgCodekeeperException, IOException, InterruptedException {
91-
return loadFromProject(settings, projectPath, null, new NullMonitor());
123+
return loadFromProject(projectPath, null);
92124
}
93125

94126
/**
95127
* Loads database from a project directory with schema filtering and monitoring.
96128
*
97-
* @param settings ISettings object
98129
* @param projectPath path to the project directory containing SQL files
99130
* @param ignoreSchemaListPath path to file containing schemas to ignore, or null for no filtering
100-
* @param monitor progress monitor for tracking the operation
101131
* @return the loaded database
102-
* @throws PgCodekeeperException if database loading is interrupted or parsing errors occur
132+
* @throws PgCodekeeperException if parsing errors occur
103133
* @throws IOException if I/O operations fail
134+
* @throws InterruptedException if operation is cancelled
104135
*/
105-
public static AbstractDatabase loadFromProject(ISettings settings, String projectPath, String ignoreSchemaListPath,
106-
IMonitor monitor)
136+
public AbstractDatabase loadFromProject(String projectPath, String ignoreSchemaListPath)
107137
throws PgCodekeeperException, IOException, InterruptedException {
108138
var ignoreSchemaList = IIgnoreList.parseIgnoreList(ignoreSchemaListPath, new IgnoreSchemaList());
109139
var loader = new ProjectLoader(projectPath, settings, monitor, new ArrayList<>(), ignoreSchemaList);
@@ -113,25 +143,23 @@ public static AbstractDatabase loadFromProject(ISettings settings, String projec
113143
/**
114144
* Loads database from a database dump file and monitoring.
115145
*
116-
* @param settings ISettings object
117146
* @param dumpPath path to the database dump file
118-
* @param monitor progress monitor for tracking the operation
119147
* @return the loaded database
120148
* @throws IOException if I/O operations fail
121-
* @throws PgCodekeeperException if database loading is interrupted or parsing errors occur
149+
* @throws PgCodekeeperException if parsing errors occur
150+
* @throws InterruptedException if operation is cancelled
122151
*/
123-
public static AbstractDatabase loadFromDump(ISettings settings, String dumpPath, IMonitor monitor)
152+
public AbstractDatabase loadFromDump(String dumpPath)
124153
throws IOException, PgCodekeeperException, InterruptedException {
125-
var loader = new PgDumpLoader(Path.of(dumpPath), settings, monitor);
154+
var loader = new PgDumpLoader(Path.of(dumpPath), settings);
126155
return loadDatabaseFromLoader(loader);
127156
}
128157

129-
private static AbstractDatabase loadDatabaseFromLoader(DatabaseLoader loader) throws IOException,
158+
private AbstractDatabase loadDatabaseFromLoader(DatabaseLoader loader) throws IOException,
130159
PgCodekeeperException, InterruptedException {
131-
AbstractDatabase db;
132-
db = loader.loadAndAnalyze();
160+
AbstractDatabase db = needAnalyze ? loader.loadAndAnalyze() : loader.load();
133161

134-
if (!loader.getErrors().isEmpty()) {
162+
if (!ignoreErrors && !loader.getErrors().isEmpty()) {
135163
var errors = loader.getErrors().stream()
136164
.map(Object::toString)
137165
.collect(Collectors.joining());

src/test/java/org/pgcodekeeper/core/api/PgCodeKeeperApiTest.java

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
import org.junit.jupiter.api.BeforeEach;
1919
import org.junit.jupiter.api.Test;
2020
import org.junit.jupiter.api.io.TempDir;
21+
import org.junit.jupiter.params.ParameterizedTest;
22+
import org.junit.jupiter.params.provider.ValueSource;
2123
import org.pgcodekeeper.core.PgCodekeeperException;
22-
import org.pgcodekeeper.core.schema.AbstractDatabase;
2324
import org.pgcodekeeper.core.settings.CoreSettings;
2425
import org.pgcodekeeper.core.monitor.NullMonitor;
2526

@@ -48,23 +49,29 @@ protected void initSettings() {
4849
settings = new CoreSettings();
4950
}
5051

51-
@Test
52-
void testDiff() throws PgCodekeeperException, IOException, InterruptedException {
53-
var testName = "test_diff";
54-
var oldDb = loadDatabaseFromDump(testName + ORIGINAL);
55-
var newDb = loadDatabaseFromDump(testName + NEW);
52+
@ParameterizedTest
53+
@ValueSource(strings = {
54+
"test_diff"
55+
})
56+
void diffTest(String testName) throws PgCodekeeperException, IOException, InterruptedException {
57+
var df = new DatabaseFactory(settings);
58+
var oldDb = df.loadFromDump(getFilePath(testName + ORIGINAL));
59+
var newDb = df.loadFromDump(getFilePath(testName + NEW));
5660
var expectedDiff = getExpectedDiff(testName);
5761

5862
String actual = PgCodeKeeperApi.diff(settings, oldDb, newDb);
5963

6064
assertEquals(expectedDiff, actual);
6165
}
6266

63-
@Test
64-
void testDiffWithIgnoreList() throws PgCodekeeperException, IOException, InterruptedException {
65-
var testName = "test_ignore";
66-
var oldDb = loadDatabaseFromDump(testName + ORIGINAL);
67-
var newDb = loadDatabaseFromDump(testName + NEW);
67+
@ParameterizedTest
68+
@ValueSource(strings = {
69+
"test_ignore"
70+
})
71+
void diffWithIgnoreListTest(String testName) throws PgCodekeeperException, IOException, InterruptedException {
72+
var df = new DatabaseFactory(settings);
73+
var oldDb = df.loadFromDump(getFilePath(testName + ORIGINAL));
74+
var newDb = df.loadFromDump(getFilePath(testName + NEW));
6875
var ignoreListPath = getFilePath("ignore.pgcodekeeperignore");
6976
var expectedDiff = getExpectedDiff(testName);
7077

@@ -74,9 +81,10 @@ void testDiffWithIgnoreList() throws PgCodekeeperException, IOException, Interru
7481
}
7582

7683
@Test
77-
void testExport(@TempDir Path tempDir) throws PgCodekeeperException, IOException, InterruptedException {
84+
void exportTest(@TempDir Path tempDir) throws PgCodekeeperException, IOException, InterruptedException {
7885
var dumpFileName = "test_export.sql";
79-
var db = loadDatabaseFromDump(dumpFileName);
86+
var df = new DatabaseFactory(settings);
87+
var db = df.loadFromDump(getFilePath(dumpFileName));
8088
var exportedTableFile = tempDir.resolve(TABLES_DIRECTORY + "test_table.sql");
8189
var expectedContent = getFileContent(dumpFileName);
8290

@@ -86,8 +94,9 @@ void testExport(@TempDir Path tempDir) throws PgCodekeeperException, IOException
8694
}
8795

8896
@Test
89-
void testExportWithIgnoreList(@TempDir Path tempDir) throws PgCodekeeperException, IOException, InterruptedException {
90-
var db = loadDatabaseFromDump("test_export_with_ignore_list.sql");
97+
void exportWithIgnoreListTest(@TempDir Path tempDir) throws PgCodekeeperException, IOException, InterruptedException {
98+
var df = new DatabaseFactory(settings);
99+
var db = df.loadFromDump(getFilePath("test_export_with_ignore_list.sql"));
91100
var exportedTableFile = tempDir.resolve(TABLES_DIRECTORY + "test_table.sql");
92101
var ignoredTableFile = tempDir.resolve(TABLES_DIRECTORY + "ignored_table.sql");
93102
var expectedContent = getFileContent("test_export_with_ignore_list_exported.sql");
@@ -100,11 +109,12 @@ void testExportWithIgnoreList(@TempDir Path tempDir) throws PgCodekeeperExceptio
100109
}
101110

102111
@Test
103-
void testUpdateProject(@TempDir Path tempDir) throws PgCodekeeperException, IOException, InterruptedException {
112+
void updateProjectTest(@TempDir Path tempDir) throws PgCodekeeperException, IOException, InterruptedException {
104113
// Setup project structure with initial tables
105114
setupUpdateProjectStructure(tempDir);
106-
var oldDb = DatabaseFactory.loadFromProject(settings, tempDir.toString());
107-
var newDb = loadDatabaseFromDump("test_update_project_new_dump.sql");
115+
var df = new DatabaseFactory(settings);
116+
var oldDb = df.loadFromProject(tempDir.toString());
117+
var newDb = df.loadFromDump(getFilePath("test_update_project_new_dump.sql"));
108118
var expectedContent = getFileContent("test_update_project_new_dump.sql");
109119

110120
Path tablesDir = tempDir.resolve(TABLES_DIRECTORY);
@@ -119,11 +129,12 @@ void testUpdateProject(@TempDir Path tempDir) throws PgCodekeeperException, IOEx
119129
}
120130

121131
@Test
122-
void testUpdateProjectWithIgnoreList(@TempDir Path tempDir) throws PgCodekeeperException, IOException, InterruptedException {
132+
void updateProjectWithIgnoreListTest(@TempDir Path tempDir) throws PgCodekeeperException, IOException, InterruptedException {
123133
// Setup project structure with initial tables
124134
setupUpdateProjectStructure(tempDir);
125-
var oldDb = DatabaseFactory.loadFromProject(settings, tempDir.toString(), null, null);
126-
var newDb = loadDatabaseFromDump("test_update_project_new_dump.sql");
135+
var df = new DatabaseFactory(settings);
136+
var oldDb = df.loadFromProject(tempDir.toString());
137+
var newDb = df.loadFromDump(getFilePath("test_update_project_new_dump.sql"));
127138
var ignoreListPath = getFilePath("test_update_project_ignore_list.pgcodekeeperignore");
128139

129140
var expectedFirstTableContent = getFileContent("test_update_project_old_first_table.sql");
@@ -168,10 +179,6 @@ private String getFileContent(String fileName) throws IOException {
168179
return Files.readString(path);
169180
}
170181

171-
private AbstractDatabase loadDatabaseFromDump(String fileName) throws PgCodekeeperException, IOException, InterruptedException {
172-
return DatabaseFactory.loadFromDump(settings, getFilePath(fileName), new NullMonitor());
173-
}
174-
175182
private String getExpectedDiff(String baseName) throws IOException {
176183
return getFileContent(baseName + DIFF);
177184
}
@@ -181,6 +188,4 @@ private void assertFileContent(Path filePath, String expectedContent) throws IOE
181188
var actualContent = Files.readString(filePath);
182189
assertEquals(expectedContent, actualContent);
183190
}
184-
185-
186191
}

0 commit comments

Comments
 (0)