Project

General

Profile

SchemaComparator.java

proposal for Schema Comparator service - Boris Schegolev, 08/01/2022 03:42 PM

Download (4.25 KB)

 
1
package com.goldencode.p2j.persist.orm;
2

    
3
import com.goldencode.p2j.persist.Database;
4
import com.goldencode.p2j.persist.PersistenceException;
5

    
6
import java.io.IOException;
7
import java.sql.Connection;
8
import java.util.ArrayList;
9
import java.util.List;
10

    
11
/**
12
 * JDBC schema comparator. Compares current DB schema state with last known state. Last known state may be provided.
13
 */
14
public class SchemaComparator {
15

    
16
    /**
17
     * Get an instance of the Comparator, load the current database state for use in comparison.
18
     *
19
     * @param database database to connect to
20
     * @return Comparator instance
21
     */
22
    public static SchemaComparator saveInitialState(Database database) {
23
        SchemaComparator schemaComparator = new SchemaComparator(database);
24
        schemaComparator.saveLastKnownState(null);
25
        return schemaComparator;
26
    }
27

    
28
    /**
29
     * Get an instance of the Comparator, assuming the current database state is already loaded.
30
     *
31
     * @param database database to connect to
32
     * @return Comparator instance
33
     */
34
    public static SchemaComparator getInstanceExistingState(Database database) {
35
        return new SchemaComparator(database);
36
    }
37

    
38
    private final Database database;
39

    
40
    private SchemaComparator(Database database) {
41
        this.database = database;
42
    }
43

    
44
    /**
45
     * Compare current state with last known state.
46
     *
47
     * @return ComparisonResult instance
48
     * @throws IOException translated from PersistenceException
49
     */
50
    public ComparisonResult compareWithPrevious() throws IOException {
51
        Object previousState = loadLastKnownState();
52

    
53
        return compare(previousState);
54
    }
55

    
56
    /**
57
     * Compare current state with given state.
58
     *
59
     * @param previousState previous known state for comparison
60
     * @return ComparisonResult instance
61
     * @throws IOException translated from PersistenceException
62
     */
63
    // TODO: use specific type for previousState
64
    public ComparisonResult compare(Object previousState) throws IOException {
65
        try (Session session = new Session(database))
66
        {
67
            Connection conn = session.getConnection();
68
            ComparisonResult comparisonResult = new ComparisonResult();
69

    
70
            getAndCompareTables(conn, previousState, comparisonResult);
71
            getAndCompareColumns(conn, previousState, comparisonResult);
72
            getAndCompareIndexes(conn, previousState, comparisonResult);
73

    
74
            if (!comparisonResult.isSame())
75
            {
76
                saveLastKnownState(comparisonResult.getState());
77
            }
78

    
79
            return comparisonResult;
80

    
81
        } catch (PersistenceException e) {
82
            throw new IOException("Connection failed during comparison", e);
83
        }
84
    }
85

    
86
    private Object loadLastKnownState() {
87
        // TODO
88
        return null;
89
    }
90

    
91
    private void saveLastKnownState(Object newState) {
92
        // TODO: persist state info
93
    }
94

    
95
    private void getAndCompareTables(Connection conn, Object previousState, ComparisonResult comparisonResult) {
96
        // TODO: load info from conn
97
        if (previousState != null)
98
        {
99
            // TODO: compare with previous state
100
        }
101
        // TODO: fill comparison result
102
    }
103

    
104
    private void getAndCompareColumns(Connection conn, Object previousState, ComparisonResult comparisonResult) {
105
        // TODO: load info from conn
106
        if (previousState != null)
107
        {
108
            // TODO: compare with previous state
109
        }
110
        // TODO: fill comparison result
111
    }
112

    
113
    private void getAndCompareIndexes(Connection conn, Object previousState, ComparisonResult comparisonResult) {
114
        // TODO: load info from conn
115
        if (previousState != null)
116
        {
117
            // TODO: compare with previous state
118
        }
119
        // TODO: fill comparison result
120
    }
121

    
122
    /**
123
     * Result of schema comparison.
124
     *
125
     * TODO: could be immutable, requires builder
126
     */
127
    public static class ComparisonResult {
128

    
129
        private Object state = null;
130
        private List<Object> differences = new ArrayList<>();
131

    
132
        public boolean isSame() {
133
            return differences.isEmpty();
134
        }
135

    
136
        public List<Object> getDifferences() {
137
            return differences;
138
        }
139

    
140
        private Object getState() {
141
            return state;
142
        }
143
    }
144
}