Skip to content

Commit 997044c

Browse files
committed
Merge branch 'DBTOOLS-1939-add-lib-loading-to-project' into 'master'
DBTOOLS-1939 added lib loading to project See merge request codekeeper/pgcodekeeper-core!220
2 parents dcc85c4 + d16fdab commit 997044c

15 files changed

Lines changed: 304 additions & 8 deletions

File tree

src/main/java/org/pgcodekeeper/core/database/api/IDatabaseProvider.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.pgcodekeeper.core.utils.InputStreamProvider;
3030

3131
import java.nio.file.Path;
32+
import java.util.Collection;
3233
import java.util.List;
3334

3435
/**
@@ -109,6 +110,21 @@ IProjectUpdater getProjectUpdater(IDatabase newDb, IDatabase oldDb, List<TreeEle
109110
*/
110111
IProjectLoader getProjectLoader(Path path, DiffSettings diffSettings);
111112

113+
/**
114+
* @param path path to project directory
115+
* @param diffSettings unified context object containing settings, monitor, ignore schema list, and error accumulator
116+
* @param libXmls paths to XML files with library dependency definitions
117+
* @param libs paths to library dependencies
118+
* @param libsWithoutPriv paths to library dependencies with ignored privileges
119+
* @param metaPath path to metadata directory for storing downloaded and unzipped library files, may be null
120+
* if no ZIP or URI libraries are expected
121+
* @return project loader for the DBMS
122+
* @see IProjectLoader
123+
* @see DiffSettings
124+
*/
125+
IProjectLoader getProjectLoader(Path path, DiffSettings diffSettings, Collection<String> libXmls,
126+
Collection<String> libs, Collection<String> libsWithoutPriv, Path metaPath);
127+
112128
/**
113129
* @param diffSettings configuration settings
114130
* @return return script builder

src/main/java/org/pgcodekeeper/core/database/api/schema/IStatement.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ default boolean isOwned() {
138138
*/
139139
Set<IPrivilege> getPrivileges();
140140

141+
/**
142+
* Removes all privileges from this statement.
143+
*/
144+
void clearPrivileges();
145+
141146
/**
142147
* Gets the SQL representation of this statement with optional formatting.
143148
*

src/main/java/org/pgcodekeeper/core/database/base/loader/AbstractProjectLoader.java

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,19 @@
1717

1818
import org.pgcodekeeper.core.database.api.loader.IProjectLoader;
1919
import org.pgcodekeeper.core.database.api.schema.IDatabase;
20+
import org.pgcodekeeper.core.database.api.schema.IPrivilege;
21+
import org.pgcodekeeper.core.database.api.schema.ITable;
22+
import org.pgcodekeeper.core.database.base.schema.AbstractStatement;
23+
import org.pgcodekeeper.core.database.base.schema.StatementOverride;
24+
import org.pgcodekeeper.core.library.LibraryXmlStore;
2025
import org.pgcodekeeper.core.settings.DiffSettings;
2126
import org.pgcodekeeper.core.utils.Utils;
2227

2328
import java.io.IOException;
2429
import java.nio.file.Files;
2530
import java.nio.file.Path;
26-
import java.util.ArrayDeque;
27-
import java.util.Locale;
28-
import java.util.Queue;
31+
import java.nio.file.Paths;
32+
import java.util.*;
2933
import java.util.function.Predicate;
3034
import java.util.stream.Stream;
3135

@@ -39,14 +43,32 @@ public abstract class AbstractProjectLoader<T extends IDatabase> extends Abstrac
3943

4044
private static final String IGNORE_FILE = ".pgcodekeeperignore";
4145
private static final String IGNORE_SCHEMA_FILE = ".pgcodekeeperignoreschema";
46+
private static final String OVERRIDES_DIR = "OVERRIDES";
4247

48+
protected final Path metaPath;
49+
protected final Map<AbstractStatement, StatementOverride> overrides = new LinkedHashMap<>();
4350
protected final Queue<AbstractDumpLoader<T>> dumpLoaders = new ArrayDeque<>();
4451

52+
protected boolean isOverrideMode;
53+
4554
private final Path dirPath;
55+
private final Collection<String> libXmls;
56+
private final Collection<String> libs;
57+
private final Collection<String> libsWithoutPriv;
4658

4759
protected AbstractProjectLoader(Path dirPath, DiffSettings diffSettings) {
60+
this(dirPath, diffSettings, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(),
61+
null);
62+
}
63+
64+
protected AbstractProjectLoader(Path dirPath, DiffSettings diffSettings, Collection<String> libXmls,
65+
Collection<String> libs, Collection<String> libsWithoutPriv, Path metaPath) {
4866
super(diffSettings);
4967
this.dirPath = dirPath;
68+
this.libXmls = libXmls;
69+
this.libs = libs;
70+
this.libsWithoutPriv = libsWithoutPriv;
71+
this.metaPath = metaPath;
5072
readIgnoreLists();
5173
}
5274

@@ -55,13 +77,17 @@ public T load() throws InterruptedException, IOException {
5577
T db = createDatabase();
5678
loadStructure(dirPath, db);
5779
finishLoaders();
80+
loadLibraries(db);
81+
loadOverrides(db);
5882
return db;
5983
}
6084

6185
protected abstract T createDatabase();
6286

6387
protected abstract AbstractDumpLoader<T> createDumpLoader(Path file);
6488

89+
protected abstract AbstractLibraryLoader<T> createLibraryLoader(T db);
90+
6591
protected abstract void loadStructure(Path dir, T db) throws InterruptedException, IOException;
6692

6793
protected void loadSubdir(Path dir, String sub, T db) throws IOException {
@@ -79,6 +105,9 @@ protected void loadSubdir(Path dir, String sub, T db, Predicate<String> checkFil
79105
.sorted()) {
80106
for (Path f : Utils.streamIterator(files)) {
81107
var loader = createDumpLoader(f);
108+
if (isOverrideMode) {
109+
loader.setOverridesMap(overrides);
110+
}
82111
loader.loadWithoutAnalyze(db, antlrTasks);
83112
dumpLoaders.add(loader);
84113
}
@@ -99,6 +128,62 @@ protected boolean filterFile(Path f, Predicate<String> checkFilename) {
99128
return checkFilename == null || checkFilename.test(fileName);
100129
}
101130

131+
private void loadOverrides(T db) throws IOException, InterruptedException {
132+
Path overridesDir = dirPath.resolve(OVERRIDES_DIR);
133+
if (getSettings().isIgnorePrivileges() || !Files.isDirectory(overridesDir)) {
134+
return;
135+
}
136+
137+
isOverrideMode = true;
138+
try {
139+
loadStructure(overridesDir, db);
140+
finishLoaders();
141+
replaceOverrides();
142+
} finally {
143+
isOverrideMode = false;
144+
}
145+
}
146+
147+
private void replaceOverrides() {
148+
Iterator<Map.Entry<AbstractStatement, StatementOverride>> iterator = overrides.entrySet().iterator();
149+
while (iterator.hasNext()) {
150+
Map.Entry<AbstractStatement, StatementOverride> entry = iterator.next();
151+
iterator.remove();
152+
153+
AbstractStatement st = entry.getKey();
154+
StatementOverride override = entry.getValue();
155+
if (override.getOwner() != null) {
156+
st.setOwner(override.getOwner());
157+
}
158+
159+
if (!override.getPrivileges().isEmpty()) {
160+
replacePrivileges(st, override);
161+
}
162+
}
163+
}
164+
165+
private void replacePrivileges(AbstractStatement st, StatementOverride override) {
166+
st.clearPrivileges();
167+
if (st instanceof ITable table) {
168+
for (var col : table.getColumns()) {
169+
col.clearPrivileges();
170+
}
171+
}
172+
for (IPrivilege privilege : override.getPrivileges()) {
173+
st.addPrivilege(privilege);
174+
}
175+
}
176+
177+
private void loadLibraries(T db) throws IOException, InterruptedException {
178+
var libraryLoader = createLibraryLoader(db);
179+
180+
for (String xml : libXmls) {
181+
libraryLoader.loadXml(new LibraryXmlStore(Paths.get(xml)));
182+
}
183+
libraryLoader.loadLibraries(false, libs);
184+
libraryLoader.loadLibraries(true, libsWithoutPriv);
185+
}
186+
102187
private void readIgnoreLists() {
103188
try {
104189
Path ignoreFile = dirPath.resolve(IGNORE_FILE);

src/main/java/org/pgcodekeeper/core/database/base/schema/AbstractStatement.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,12 @@ public void addPrivilege(IPrivilege privilege) {
341341
resetHash();
342342
}
343343

344+
@Override
345+
public void clearPrivileges() {
346+
privileges.clear();
347+
resetHash();
348+
}
349+
344350
@Override
345351
public String getOwner() {
346352
return owner;

src/main/java/org/pgcodekeeper/core/database/base/schema/meta/MetaStatement.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@
1515
*******************************************************************************/
1616
package org.pgcodekeeper.core.database.base.schema.meta;
1717

18-
import java.io.*;
19-
import java.util.Set;
20-
import java.util.function.UnaryOperator;
21-
import java.util.stream.Stream;
22-
2318
import org.pgcodekeeper.core.database.api.formatter.IFormatConfiguration;
2419
import org.pgcodekeeper.core.database.api.schema.*;
2520
import org.pgcodekeeper.core.script.SQLScript;
2621
import org.pgcodekeeper.core.settings.ISettings;
2722

23+
import java.io.Serial;
24+
import java.io.Serializable;
25+
import java.util.Set;
26+
import java.util.function.UnaryOperator;
27+
import java.util.stream.Stream;
28+
2829
/**
2930
* Base class for all database metadata statement objects.
3031
* Provides common functionality for accessing object location, names, and comments.
@@ -181,6 +182,11 @@ public Set<IPrivilege> getPrivileges() {
181182
throw new UnsupportedOperationException();
182183
}
183184

185+
@Override
186+
public void clearPrivileges() {
187+
throw new UnsupportedOperationException();
188+
}
189+
184190
@Override
185191
public String getSQL(boolean isFormatted, ISettings settings) {
186192
throw new UnsupportedOperationException();

src/main/java/org/pgcodekeeper/core/database/ch/ChDatabaseProvider.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.pgcodekeeper.core.utils.InputStreamProvider;
3434

3535
import java.nio.file.Path;
36+
import java.util.Collection;
3637
import java.util.List;
3738

3839
/**
@@ -87,6 +88,12 @@ public ChProjectLoader getProjectLoader(Path path, DiffSettings diffSettings) {
8788
return new ChProjectLoader(path, diffSettings);
8889
}
8990

91+
@Override
92+
public ChProjectLoader getProjectLoader(Path path, DiffSettings diffSettings, Collection<String> libXmls,
93+
Collection<String> libs, Collection<String> libsWithoutPriv, Path metaPath) {
94+
return new ChProjectLoader(path, diffSettings, libXmls, libs, libsWithoutPriv, metaPath);
95+
}
96+
9097
@Override
9198
public IScriptBuilder getScriptBuilder(DiffSettings diffSettings) {
9299
return new ChScriptBuilder(diffSettings);

src/main/java/org/pgcodekeeper/core/database/ch/loader/ChProjectLoader.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import org.pgcodekeeper.core.database.api.schema.DbObjType;
1919
import org.pgcodekeeper.core.database.base.loader.AbstractDumpLoader;
20+
import org.pgcodekeeper.core.database.base.loader.AbstractLibraryLoader;
2021
import org.pgcodekeeper.core.database.base.loader.AbstractProjectLoader;
2122
import org.pgcodekeeper.core.database.ch.project.ChWorkDirs;
2223
import org.pgcodekeeper.core.database.ch.schema.ChDatabase;
@@ -26,6 +27,8 @@
2627
import java.io.IOException;
2728
import java.nio.file.Files;
2829
import java.nio.file.Path;
30+
import java.util.Collection;
31+
import java.util.HashSet;
2932
import java.util.stream.Stream;
3033

3134
/**
@@ -37,6 +40,11 @@ public ChProjectLoader(Path dirPath, DiffSettings diffSettings) {
3740
super(dirPath, diffSettings);
3841
}
3942

43+
public ChProjectLoader(Path dirPath, DiffSettings diffSettings, Collection<String> libXmls,
44+
Collection<String> libs, Collection<String> libsWithoutPriv, Path metaPath) {
45+
super(dirPath, diffSettings, libXmls, libs, libsWithoutPriv, metaPath);
46+
}
47+
4048
@Override
4149
protected ChDatabase createDatabase() {
4250
return new ChDatabase();
@@ -47,6 +55,11 @@ protected AbstractDumpLoader<ChDatabase> createDumpLoader(Path file) {
4755
return new ChDumpLoader(file, diffSettings);
4856
}
4957

58+
@Override
59+
protected AbstractLibraryLoader<ChDatabase> createLibraryLoader(ChDatabase db) {
60+
return new ChLibraryLoader(db, metaPath, new HashSet<>(), diffSettings);
61+
}
62+
5063
@Override
5164
protected void loadStructure(Path dir, ChDatabase db) throws IOException {
5265
for (String dirName : ChWorkDirs.getDirectoryNames()) {

src/main/java/org/pgcodekeeper/core/database/ms/MsDatabaseProvider.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.pgcodekeeper.core.utils.InputStreamProvider;
3434

3535
import java.nio.file.Path;
36+
import java.util.Collection;
3637
import java.util.List;
3738

3839
/**
@@ -87,6 +88,12 @@ public MsProjectLoader getProjectLoader(Path path, DiffSettings diffSettings) {
8788
return new MsProjectLoader(path, diffSettings);
8889
}
8990

91+
@Override
92+
public MsProjectLoader getProjectLoader(Path path, DiffSettings diffSettings, Collection<String> libXmls,
93+
Collection<String> libs, Collection<String> libsWithoutPriv, Path metaPath) {
94+
return new MsProjectLoader(path, diffSettings, libXmls, libs, libsWithoutPriv, metaPath);
95+
}
96+
9097
@Override
9198
public IScriptBuilder getScriptBuilder(DiffSettings diffSettings) {
9299
return new MsScriptBuilder(diffSettings);

src/main/java/org/pgcodekeeper/core/database/ms/loader/MsProjectLoader.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.pgcodekeeper.core.database.api.schema.ObjectLocation;
2020
import org.pgcodekeeper.core.database.api.schema.ObjectReference;
2121
import org.pgcodekeeper.core.database.base.loader.AbstractDumpLoader;
22+
import org.pgcodekeeper.core.database.base.loader.AbstractLibraryLoader;
2223
import org.pgcodekeeper.core.database.base.loader.AbstractProjectLoader;
2324
import org.pgcodekeeper.core.database.base.parser.AntlrTaskManager;
2425
import org.pgcodekeeper.core.database.ms.project.MsWorkDirs;
@@ -29,6 +30,8 @@
2930

3031
import java.io.IOException;
3132
import java.nio.file.Path;
33+
import java.util.Collection;
34+
import java.util.HashSet;
3235

3336
/**
3437
* MS SQL Server project loader for loading database schemas from project directory structures.
@@ -39,6 +42,11 @@ public MsProjectLoader(Path dirPath, DiffSettings diffSettings) {
3942
super(dirPath, diffSettings);
4043
}
4144

45+
public MsProjectLoader(Path dirPath, DiffSettings diffSettings, Collection<String> libXmls,
46+
Collection<String> libs, Collection<String> libsWithoutPriv, Path metaPath) {
47+
super(dirPath, diffSettings, libXmls, libs, libsWithoutPriv, metaPath);
48+
}
49+
4250
@Override
4351
protected MsDatabase createDatabase() {
4452
return new MsDatabase();
@@ -49,6 +57,11 @@ protected AbstractDumpLoader<MsDatabase> createDumpLoader(Path file) {
4957
return new MsDumpLoader(file, diffSettings);
5058
}
5159

60+
@Override
61+
protected AbstractLibraryLoader<MsDatabase> createLibraryLoader(MsDatabase db) {
62+
return new MsLibraryLoader(db, metaPath, new HashSet<>(), diffSettings);
63+
}
64+
5265
@Override
5366
protected void loadStructure(Path dir, MsDatabase db) throws InterruptedException, IOException {
5467
Path securityFolder = dir.resolve(MsWorkDirs.SECURITY);

src/main/java/org/pgcodekeeper/core/database/pg/PgDatabaseProvider.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.pgcodekeeper.core.utils.InputStreamProvider;
3434

3535
import java.nio.file.Path;
36+
import java.util.Collection;
3637
import java.util.List;
3738

3839
/**
@@ -89,6 +90,12 @@ public PgProjectLoader getProjectLoader(Path path, DiffSettings diffSettings) {
8990
return new PgProjectLoader(path, diffSettings);
9091
}
9192

93+
@Override
94+
public PgProjectLoader getProjectLoader(Path path, DiffSettings diffSettings, Collection<String> libXmls,
95+
Collection<String> libs, Collection<String> libsWithoutPriv, Path metaPath) {
96+
return new PgProjectLoader(path, diffSettings, libXmls, libs, libsWithoutPriv, metaPath);
97+
}
98+
9299
@Override
93100
public IScriptBuilder getScriptBuilder(DiffSettings diffSettings) {
94101
return new PgScriptBuilder(diffSettings);

0 commit comments

Comments
 (0)