Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe

Commits:

12 changed files:

Changes:

  • core/persistence/test/src/test/java/org/nuiton/topia/persistence/jdbc/JdbcHelperH2Test.java
    ... ... @@ -30,6 +30,7 @@ import org.junit.Assert;
    30 30
     import org.junit.Before;
    
    31 31
     import org.junit.ClassRule;
    
    32 32
     import org.junit.Test;
    
    33
    +import org.nuiton.topia.service.migration.version.MigrationServiceSqlHelper;
    
    33 34
     
    
    34 35
     import java.sql.SQLException;
    
    35 36
     
    
    ... ... @@ -54,20 +55,17 @@ public class JdbcHelperH2Test extends PersistenceTestSupportWrite {
    54 55
     
    
    55 56
         @Test
    
    56 57
         public void isTableExist() throws SQLException {
    
    57
    -        boolean actual = jdbcHelper.isTableExist("Public", "Tms_version");
    
    58
    -        Assert.assertTrue(actual);
    
    58
    +        Assert.assertTrue(jdbcHelper.isTableExist(MigrationServiceSqlHelper.CURRENT.schemaName(), MigrationServiceSqlHelper.CURRENT.tableName()));
    
    59
    +        Assert.assertTrue(jdbcHelper.isTableExist(MigrationServiceSqlHelper.CURRENT.schemaName().toUpperCase(), MigrationServiceSqlHelper.CURRENT.tableName()));
    
    60
    +        Assert.assertTrue(jdbcHelper.isTableExist(MigrationServiceSqlHelper.CURRENT.schemaName().toUpperCase(), MigrationServiceSqlHelper.CURRENT.tableName().toUpperCase()));
    
    59 61
     
    
    60
    -        actual = jdbcHelper.isTableExist("PUBLIC", "tms_version-fake");
    
    61
    -        Assert.assertFalse(actual);
    
    62
    +        Assert.assertFalse(jdbcHelper.isTableExist(MigrationServiceSqlHelper.CURRENT.schemaName(), MigrationServiceSqlHelper.CURRENT.tableName()+"-Fake"));
    
    62 63
         }
    
    63 64
     
    
    64 65
         @Test
    
    65 66
         public void isSchemaExist() throws SQLException {
    
    66
    -        boolean actual = jdbcHelper.isSchemaExist("Public");
    
    67
    -        Assert.assertTrue(actual);
    
    68
    -
    
    69
    -        actual = jdbcHelper.isSchemaExist("PUBLIC-fake");
    
    70
    -        Assert.assertFalse(actual);
    
    67
    +        Assert.assertTrue(jdbcHelper.isSchemaExist("Public"));
    
    68
    +        Assert.assertFalse(jdbcHelper.isSchemaExist("PUBLIC-fake"));
    
    71 69
         }
    
    72 70
     
    
    73 71
     }

  • core/persistence/test/src/test/java/org/nuiton/topia/persistence/jdbc/JdbcSecurityHelperH2Test.java
    ... ... @@ -31,6 +31,7 @@ import org.junit.Assert;
    31 31
     import org.junit.Before;
    
    32 32
     import org.junit.ClassRule;
    
    33 33
     import org.junit.Test;
    
    34
    +import org.nuiton.topia.service.migration.version.MigrationServiceSqlHelper;
    
    34 35
     
    
    35 36
     import java.util.List;
    
    36 37
     import java.util.Set;
    
    ... ... @@ -62,10 +63,9 @@ public class JdbcSecurityHelperH2Test extends PersistenceTestSupportWrite {
    62 63
             Assert.assertNotNull(actual);
    
    63 64
             Assert.assertEquals(0, actual.size());
    
    64 65
     
    
    65
    -        actual = securityHelper.getTables(Set.of("PUbLIC"), Set.of());
    
    66
    +        actual = securityHelper.getTables(Set.of(MigrationServiceSqlHelper.CURRENT.schemaName()), Set.of());
    
    66 67
             Assert.assertNotNull(actual);
    
    67
    -        Assert.assertEquals(1, actual.size());
    
    68
    -        Assert.assertEquals(List.of(Pair.of("PUBLIC", "TMS_VERSION")), actual);
    
    68
    +        Assert.assertTrue(actual.contains(Pair.of(MigrationServiceSqlHelper.CURRENT.schemaName().toUpperCase(), MigrationServiceSqlHelper.CURRENT.tableName().toUpperCase())));
    
    69 69
         }
    
    70 70
     
    
    71 71
         @Test
    
    ... ... @@ -90,7 +90,7 @@ public class JdbcSecurityHelperH2Test extends PersistenceTestSupportWrite {
    90 90
     
    
    91 91
         @Test
    
    92 92
         public void getTablePrivileges() {
    
    93
    -        Set<String> actual = securityHelper.getTablePrivileges("PUbLIC", "Tms_VERSION");
    
    93
    +        Set<String> actual = securityHelper.getTablePrivileges(MigrationServiceSqlHelper.CURRENT.schemaName(), MigrationServiceSqlHelper.CURRENT.tableName());
    
    94 94
             Assert.assertNotNull(actual);
    
    95 95
             Assert.assertEquals(0, actual.size());
    
    96 96
         }
    

  • core/persistence/test/src/test/java/org/nuiton/topia/persistence/security/SecurityScriptHelperTest.java
    ... ... @@ -37,6 +37,7 @@ import org.junit.ClassRule;
    37 37
     import org.junit.Test;
    
    38 38
     import org.nuiton.topia.persistence.jdbc.JdbcHelper;
    
    39 39
     import org.nuiton.topia.persistence.jdbc.JdbcSecurityHelper;
    
    40
    +import org.nuiton.topia.service.migration.version.MigrationServiceSqlHelper;
    
    40 41
     
    
    41 42
     import java.sql.SQLException;
    
    42 43
     import java.util.Map;
    
    ... ... @@ -92,7 +93,7 @@ public class SecurityScriptHelperTest extends PersistenceTestSupportWrite {
    92 93
             SecurityScriptHelper securityScriptHelper = localTestMethodResource.getTopiaApplicationContext().newSecurityScriptHelper();
    
    93 94
             securityScriptHelper.applySecurity(users);
    
    94 95
     
    
    95
    -        Set<String> actual = securityHelper.getTablePrivileges("PUBLIC", "TMS_VERSION");
    
    96
    +        Set<String> actual = securityHelper.getTablePrivileges(MigrationServiceSqlHelper.CURRENT.schemaName().toUpperCase(), MigrationServiceSqlHelper.CURRENT.tableName().toUpperCase());
    
    96 97
             Assert.assertNotNull(actual);
    
    97 98
             Assert.assertEquals(4, actual.size());
    
    98 99
             Assert.assertEquals(Set.of("DELETE", "INSERT", "UPDATE", "SELECT"), actual);
    

  • toolkit/persistence/src/main/java/org/nuiton/topia/persistence/jdbc/JdbcHelper.java
    ... ... @@ -34,6 +34,8 @@ import java.sql.DriverManager;
    34 34
     import java.sql.PreparedStatement;
    
    35 35
     import java.sql.ResultSet;
    
    36 36
     import java.sql.SQLException;
    
    37
    +import java.util.LinkedList;
    
    38
    +import java.util.List;
    
    37 39
     import java.util.Objects;
    
    38 40
     
    
    39 41
     /**
    
    ... ... @@ -116,17 +118,38 @@ public abstract class JdbcHelper {
    116 118
         }
    
    117 119
     
    
    118 120
         public String runSelectOnString(String sql) throws SQLException {
    
    119
    -        return runSelect(sql, resultSet -> resultSet.next() ? resultSet.getString(1) : null);
    
    121
    +        return runSelect(sql, resultSet -> resultSet.getString(1));
    
    120 122
         }
    
    121 123
     
    
    122 124
         public <T> T runSelect(String sql, SqlFunction<ResultSet, T> function) throws SQLException {
    
    123 125
             try (Connection connection = openConnection()) {
    
    124 126
                 try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
    
    125 127
                     try (ResultSet resultSet = preparedStatement.executeQuery()) {
    
    126
    -                    return function.apply(resultSet);
    
    128
    +                    if (resultSet.next()) {
    
    129
    +                        return function.apply(resultSet);
    
    130
    +                    }
    
    131
    +                    return null;
    
    132
    +                }
    
    133
    +            }
    
    134
    +        }
    
    135
    +    }
    
    136
    +
    
    137
    +    public <T> List<T> runMultipleSelect(String sql, SqlFunction<ResultSet, T> function) throws SQLException {
    
    138
    +        List<T> result = new LinkedList<>();
    
    139
    +        try (Connection connection = openConnection()) {
    
    140
    +            try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
    
    141
    +                try (ResultSet resultSet = preparedStatement.executeQuery()) {
    
    142
    +                    while (resultSet.next()) {
    
    143
    +
    
    144
    +                        T row = function.apply(resultSet);
    
    145
    +                        if (row != null) {
    
    146
    +                            result.add(row);
    
    147
    +                        }
    
    148
    +                    }
    
    127 149
                     }
    
    128 150
                 }
    
    129 151
             }
    
    152
    +        return result;
    
    130 153
         }
    
    131 154
     
    
    132 155
         public <T> T runOnMetadata(SqlFunction<DatabaseMetaData, T> function) throws SQLException {
    

  • toolkit/persistence/src/main/java/org/nuiton/topia/persistence/jdbc/JdbcSecurityHelper.java
    ... ... @@ -161,14 +161,14 @@ public interface JdbcSecurityHelper {
    161 161
                 return getLegacyVersion();
    
    162 162
             }
    
    163 163
             try {
    
    164
    -            return MigrationServiceSqlHelper.DEFAULT.getVersion(jdbcHelper()).map(TMSVersion::toVersion).orElse(Version.VZERO);
    
    164
    +            return MigrationServiceSqlHelper.DEFAULT.getVersion(jdbcHelper()).map(TMSVersion::getVersion).orElse(Version.VZERO);
    
    165 165
             } catch (Exception e) {
    
    166
    -            // try on legacy
    
    166
    +            // try on legacy (migration may not been applied)
    
    167 167
                 return getLegacyVersion();
    
    168 168
             }
    
    169 169
         }
    
    170 170
     
    
    171 171
         private Version getLegacyVersion() {
    
    172
    -        return MigrationServiceSqlHelper.LEGACY.getVersion(jdbcHelper()).map(TMSVersion::toVersion).orElse(Version.VZERO);
    
    172
    +        return MigrationServiceSqlHelper.LEGACY.getVersion(jdbcHelper()).map(TMSVersion::getVersion).orElse(Version.VZERO);
    
    173 173
         }
    
    174 174
     }

  • toolkit/persistence/src/main/java/org/nuiton/topia/persistence/jdbc/JdbcSecurityHelperH2.java
    ... ... @@ -31,7 +31,6 @@ import org.nuiton.topia.persistence.security.SecurityScriptHelper;
    31 31
     
    
    32 32
     import java.sql.ResultSet;
    
    33 33
     import java.sql.SQLException;
    
    34
    -import java.util.ArrayList;
    
    35 34
     import java.util.Collection;
    
    36 35
     import java.util.Collections;
    
    37 36
     import java.util.HashSet;
    
    ... ... @@ -162,24 +161,21 @@ public class JdbcSecurityHelperH2 implements JdbcSecurityHelper {
    162 161
             Set<String> safeExtraTables = extraTables.stream().map(String::toLowerCase).collect(Collectors.toSet());
    
    163 162
             try {
    
    164 163
     
    
    165
    -            return jdbcHelper.runSelect("SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'TABLE'", resultSet -> {
    
    166
    -                List<Pair<String, String>> result = new ArrayList<>();
    
    167
    -                while (resultSet.next()) {
    
    168
    -                    String schemaName = resultSet.getString(1);
    
    169
    -                    String tableName = resultSet.getString(2);
    
    170
    -                    if (!safeExtraTables.contains(tableName.toLowerCase())) {
    
    171
    -                        //                        if (POSTGIS_TABLES.contains(tableName)) {
    
    172
    -                        //                            continue;
    
    173
    -                        //                        }
    
    174
    -                        if (schemaName == null || !safeSchemas.contains(schemaName.toLowerCase())) {
    
    175
    -                            continue;
    
    176
    -                        }
    
    164
    +            List<Pair<String, String>> pairs = jdbcHelper.runMultipleSelect("SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'TABLE'", resultSet -> {
    
    165
    +                String schemaName = resultSet.getString(1);
    
    166
    +                String tableName = resultSet.getString(2);
    
    167
    +                if (!safeExtraTables.contains(tableName.toLowerCase())) {
    
    168
    +                    //                        if (POSTGIS_TABLES.contains(tableName)) {
    
    169
    +                    //                            continue;
    
    170
    +                    //                        }
    
    171
    +                    if (schemaName == null || !safeSchemas.contains(schemaName.toLowerCase())) {
    
    172
    +                        return null;
    
    177 173
                         }
    
    178
    -                    result.add(Pair.of(schemaName, tableName));
    
    179 174
                     }
    
    180
    -                Collections.sort(result);
    
    181
    -                return result;
    
    175
    +                return Pair.of(schemaName, tableName);
    
    182 176
                 });
    
    177
    +            Collections.sort(pairs);
    
    178
    +            return pairs;
    
    183 179
             } catch (Exception e) {
    
    184 180
                 throw new TopiaException(e);
    
    185 181
             }
    
    ... ... @@ -188,14 +184,8 @@ public class JdbcSecurityHelperH2 implements JdbcSecurityHelper {
    188 184
         @Override
    
    189 185
         public Set<String> getRoles() {
    
    190 186
             try {
    
    191
    -            return jdbcHelper.runSelect("SELECT name FROM INFORMATION_SCHEMA.USERS;", resultSet -> {
    
    192
    -                Set<String> users = new LinkedHashSet<>();
    
    193
    -                while (resultSet.next()) {
    
    194
    -                    String name = resultSet.getString(1);
    
    195
    -                    users.add(name);
    
    196
    -                }
    
    197
    -                return users;
    
    198
    -            });
    
    187
    +            List<String> roles = jdbcHelper.runMultipleSelect("SELECT name FROM INFORMATION_SCHEMA.USERS;", resultSet -> resultSet.getString(1));
    
    188
    +            return Set.copyOf(roles);
    
    199 189
             } catch (SQLException e) {
    
    200 190
                 throw new TopiaException(e);
    
    201 191
             }
    
    ... ... @@ -204,7 +194,7 @@ public class JdbcSecurityHelperH2 implements JdbcSecurityHelper {
    204 194
         @Override
    
    205 195
         public boolean isOwner() {
    
    206 196
             try {
    
    207
    -            return jdbcHelper.runSelect("SELECT t.* FROM INFORMATION_SCHEMA.SCHEMATA t WHERE SCHEMA_NAME = 'PUBLIC' AND SCHEMA_OWNER = CURRENT_USER", ResultSet::next);
    
    197
    +            return jdbcHelper.runSelect("SELECT t.* FROM INFORMATION_SCHEMA.SCHEMATA t WHERE SCHEMA_NAME = 'PUBLIC' AND SCHEMA_OWNER = CURRENT_USER", r-> true);
    
    208 198
             } catch (SQLException e) {
    
    209 199
                 throw new TopiaException(e);
    
    210 200
             }
    
    ... ... @@ -213,7 +203,7 @@ public class JdbcSecurityHelperH2 implements JdbcSecurityHelper {
    213 203
         @Override
    
    214 204
         public boolean isSuperUser() {
    
    215 205
             try {
    
    216
    -            return jdbcHelper.runSelect("SELECT admin FROM INFORMATION_SCHEMA.USERS WHERE name = CURRENT_USER", resultSet -> resultSet.next() && resultSet.getBoolean(1));
    
    206
    +            return jdbcHelper.runSelect("SELECT admin FROM INFORMATION_SCHEMA.USERS WHERE name = CURRENT_USER", resultSet -> resultSet.getBoolean(1));
    
    217 207
             } catch (SQLException e) {
    
    218 208
                 throw new TopiaException(e);
    
    219 209
             }
    

  • toolkit/persistence/src/main/java/org/nuiton/topia/persistence/jdbc/JdbcSecurityHelperPostgres.java
    ... ... @@ -253,7 +253,7 @@ public class JdbcSecurityHelperPostgres implements JdbcSecurityHelper {
    253 253
         @Override
    
    254 254
         public boolean isOwner() {
    
    255 255
             try {
    
    256
    -            return jdbcHelper.runSelect("SELECT pg_catalog.pg_get_userbyid(d.datdba) FROM pg_catalog.pg_database d WHERE d.datname = (SELECT current_database())", resultSet -> resultSet.next() && Objects.equals(jdbcHelper.getJdbcConnectionUser(), resultSet.getString(1)));
    
    256
    +            return jdbcHelper.runSelect("SELECT pg_catalog.pg_get_userbyid(d.datdba) FROM pg_catalog.pg_database d WHERE d.datname = (SELECT current_database())", resultSet -> Objects.equals(jdbcHelper.getJdbcConnectionUser(), resultSet.getString(1)));
    
    257 257
             } catch (SQLException e) {
    
    258 258
                 throw new TopiaException(e);
    
    259 259
             }
    
    ... ... @@ -262,7 +262,7 @@ public class JdbcSecurityHelperPostgres implements JdbcSecurityHelper {
    262 262
         @Override
    
    263 263
         public boolean isSuperUser() {
    
    264 264
             try {
    
    265
    -            return jdbcHelper.runSelect("SELECT usesuper FROM pg_user WHERE usename = CURRENT_USER", resultSet -> resultSet.next() && resultSet.getBoolean(1));
    
    265
    +            return jdbcHelper.runSelect("SELECT usesuper FROM pg_user WHERE usename = CURRENT_USER", resultSet -> resultSet.getBoolean(1));
    
    266 266
             } catch (SQLException e) {
    
    267 267
                 throw new TopiaException(e);
    
    268 268
             }
    
    ... ... @@ -275,14 +275,8 @@ public class JdbcSecurityHelperPostgres implements JdbcSecurityHelper {
    275 275
                                                " FROM pg_proc p INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid)" +
    
    276 276
                                                " WHERE ns.nspname = 'public' AND p.proname ILIKE '%s%%';", functionPattern);
    
    277 277
             try {
    
    278
    -            return jdbcHelper.runSelect(sql, resultSet -> {
    
    279
    -                Set<String> result = new LinkedHashSet<>();
    
    280
    -                while (resultSet.next()) {
    
    281
    -                    String functionPrototype = resultSet.getString(1);
    
    282
    -                    result.add(functionPrototype);
    
    283
    -                }
    
    284
    -                return result;
    
    285
    -            });
    
    278
    +            List<String> result = jdbcHelper.runMultipleSelect(sql, resultSet -> resultSet.getString(1));
    
    279
    +            return Set.copyOf(result);
    
    286 280
             } catch (SQLException e) {
    
    287 281
                 throw new TopiaException(e);
    
    288 282
             }
    

  • toolkit/persistence/src/main/java/org/nuiton/topia/service/migration/TopiaMigrationServiceContext.java
    ... ... @@ -38,6 +38,9 @@ import org.nuiton.topia.service.migration.version.TMSVersion;
    38 38
     import java.io.IOException;
    
    39 39
     import java.nio.file.Files;
    
    40 40
     import java.nio.file.Path;
    
    41
    +import java.util.Date;
    
    42
    +import java.util.List;
    
    43
    +import java.util.Objects;
    
    41 44
     import java.util.Optional;
    
    42 45
     
    
    43 46
     /**
    
    ... ... @@ -56,11 +59,10 @@ public class TopiaMigrationServiceContext {
    56 59
          * Service configuration.
    
    57 60
          */
    
    58 61
         protected final TopiaMigrationServiceConfiguration configuration;
    
    59
    -    protected final MigrationServiceSqlHelper sqlHelper;
    
    60 62
         /**
    
    61
    -     * Jdbc helper used to perform some sql code.
    
    63
    +     * Migration sql helper (could be legacy or default).
    
    62 64
          */
    
    63
    -    private final JdbcHelper jdbcHelper;
    
    65
    +    protected final MigrationServiceSqlHelper sqlHelper;
    
    64 66
         /**
    
    65 67
          * Available migration resources found in class-path.
    
    66 68
          */
    
    ... ... @@ -74,17 +76,25 @@ public class TopiaMigrationServiceContext {
    74 76
          */
    
    75 77
         protected final boolean dbNotVersioned;
    
    76 78
         /**
    
    77
    -     * Is legacy TMSVersion table exists?
    
    79
    +     * Is legacy migration table exists? (only used with default mode)
    
    78 80
          */
    
    79 81
         protected final boolean legacyVersionTableExist;
    
    80 82
         /**
    
    81
    -     * Is TMSVersion schema exists?
    
    83
    +     * Is default migration schema exists?
    
    84
    +     */
    
    85
    +    protected final boolean versionSchemaExist;
    
    86
    +    /**
    
    87
    +     * Is default migration table exists?
    
    82 88
          */
    
    83
    -    protected boolean versionSchemaExist;
    
    89
    +    protected final boolean versionTableExist;
    
    84 90
         /**
    
    85
    -     * Is TMSVersion table exists?
    
    91
    +     * Can we apply migration versions?
    
    86 92
          */
    
    87
    -    protected boolean versionTableExist;
    
    93
    +    protected final boolean canApplyMigrationVersions;
    
    94
    +    /**
    
    95
    +     * Migration versions to apply.
    
    96
    +     */
    
    97
    +    protected final List<Version> versionsToApply;
    
    88 98
         /**
    
    89 99
          * Current database version.
    
    90 100
          */
    
    ... ... @@ -114,10 +124,11 @@ public class TopiaMigrationServiceContext {
    114 124
             try {
    
    115 125
                 versionTableExist = sqlHelper.isTableExist(jdbcHelper);
    
    116 126
                 if (versionTableExist) {
    
    127
    +                log.info("Detected standard migration table {}.", sqlHelper.gav());
    
    117 128
                     versionSchemaExist = true;
    
    118 129
                     Optional<TMSVersion> tmsVersion = sqlHelper.getVersion(jdbcHelper);
    
    119 130
                     if (tmsVersion.isPresent()) {
    
    120
    -                    v = tmsVersion.get().toVersion();
    
    131
    +                    v = tmsVersion.get().getVersion();
    
    121 132
                     }
    
    122 133
                     if (v == null) {
    
    123 134
                         log.warn(String.format("Version not found on table %s", sqlHelper.gav()));
    
    ... ... @@ -126,9 +137,10 @@ public class TopiaMigrationServiceContext {
    126 137
                     versionSchemaExist = sqlHelper.isSchemaExist(jdbcHelper);
    
    127 138
                     legacyVersionTableExist = legacySqlHelper.isTableExist(jdbcHelper);
    
    128 139
                     if (legacyVersionTableExist) {
    
    140
    +                    log.info("Detected legacy migration table {}.", sqlHelper.gav());
    
    129 141
                         Optional<TMSVersion> tmsVersion = legacySqlHelper.getVersion(jdbcHelper);
    
    130 142
                         if (tmsVersion.isPresent()) {
    
    131
    -                        v = tmsVersion.get().toVersion();
    
    143
    +                        v = tmsVersion.get().getVersion();
    
    132 144
                         }
    
    133 145
                         if (v == null) {
    
    134 146
                             log.warn(String.format("Version not found on legacy table %s", legacySqlHelper.gav()));
    
    ... ... @@ -137,6 +149,7 @@ public class TopiaMigrationServiceContext {
    137 149
                 }
    
    138 150
             } finally {
    
    139 151
                 if (v == null) {
    
    152
    +                //FIXME Is this can really happen?
    
    140 153
                     // la base dans ce cas n'est pas versionee.
    
    141 154
                     // On dit que la version de la base est 0
    
    142 155
                     // et les schema de cette version 0 doivent
    
    ... ... @@ -151,7 +164,6 @@ public class TopiaMigrationServiceContext {
    151 164
             }
    
    152 165
             return new TopiaMigrationServiceContext(configuration,
    
    153 166
                                                     sqlHelper,
    
    154
    -                                                jdbcHelper,
    
    155 167
                                                     legacyVersionTableExist,
    
    156 168
                                                     versionSchemaExist,
    
    157 169
                                                     versionTableExist,
    
    ... ... @@ -175,9 +187,10 @@ public class TopiaMigrationServiceContext {
    175 187
             try {
    
    176 188
                 versionTableExist = sqlHelper.isTableExist(jdbcHelper);
    
    177 189
                 if (versionTableExist) {
    
    190
    +                log.info("Detected legacy migration table {}.", sqlHelper.gav());
    
    178 191
                     Optional<TMSVersion> tmsVersion = sqlHelper.getVersion(jdbcHelper);
    
    179 192
                     if (tmsVersion.isPresent()) {
    
    180
    -                    v = tmsVersion.get().toVersion();
    
    193
    +                    v = tmsVersion.get().getVersion();
    
    181 194
                     }
    
    182 195
                     if (v == null) {
    
    183 196
                         log.warn(String.format("Version not found on table %s", sqlHelper.gav()));
    
    ... ... @@ -199,7 +212,6 @@ public class TopiaMigrationServiceContext {
    199 212
             }
    
    200 213
             return new TopiaMigrationServiceContext(configuration,
    
    201 214
                                                     sqlHelper,
    
    202
    -                                                jdbcHelper,
    
    203 215
                                                     false,
    
    204 216
                                                     true,
    
    205 217
                                                     versionTableExist,
    
    ... ... @@ -211,15 +223,14 @@ public class TopiaMigrationServiceContext {
    211 223
     
    
    212 224
         protected TopiaMigrationServiceContext(TopiaMigrationServiceConfiguration configuration,
    
    213 225
                                                MigrationServiceSqlHelper sqlHelper,
    
    214
    -                                           JdbcHelper jdbcHelper,
    
    215
    -                                           boolean legacyVersionTableExist, boolean versionSchemaExist,
    
    226
    +                                           boolean legacyVersionTableExist,
    
    227
    +                                           boolean versionSchemaExist,
    
    216 228
                                                boolean versionTableExist,
    
    217 229
                                                boolean dbNotVersioned,
    
    218 230
                                                Version dbVersion,
    
    219 231
                                                MigrationVersionResourceProvider resources) {
    
    220 232
             this.configuration = configuration;
    
    221 233
             this.sqlHelper = sqlHelper;
    
    222
    -        this.jdbcHelper = jdbcHelper;
    
    223 234
             this.versionSchemaExist = versionSchemaExist;
    
    224 235
             this.versionTableExist = versionTableExist;
    
    225 236
             this.dbNotVersioned = dbNotVersioned;
    
    ... ... @@ -231,26 +242,24 @@ public class TopiaMigrationServiceContext {
    231 242
             } catch (IOException e) {
    
    232 243
                 throw new IllegalStateException("Can't create scripts path", e);
    
    233 244
             }
    
    234
    -    }
    
    235 245
     
    
    236
    -    public Path getScriptPath() {
    
    237
    -        return scriptPath;
    
    238
    -    }
    
    246
    +        List<Version> allVersions = getResources().getAvailableVersions();
    
    247
    +        log.info(String.format("Detected available versions: %1$s", allVersions));
    
    239 248
     
    
    240
    -    public boolean isVersionSchemaExist() {
    
    241
    -        return versionSchemaExist;
    
    242
    -    }
    
    249
    +        versionsToApply = getResources().getVersionsAfter(dbVersion);
    
    250
    +        log.info(String.format("Detected versions to apply: %1$s", versionsToApply));
    
    243 251
     
    
    244
    -    public boolean isVersionTableExist() {
    
    245
    -        return versionTableExist;
    
    246
    -    }
    
    252
    +        Optional<TopiaMigrationServiceAskUserToMigrate> askUserToMigrate = Optional.ofNullable(configuration.getCallback());
    
    247 253
     
    
    248
    -    public boolean isLegacyVersionTableExist() {
    
    249
    -        return legacyVersionTableExist;
    
    254
    +        // ask to perform the migration
    
    255
    +        canApplyMigrationVersions = askUserToMigrate.map(c -> c.canIMigrate(getDbVersion(), versionsToApply)).orElse(true);
    
    256
    +        if (!canApplyMigrationVersions) {
    
    257
    +            log.warn("Detected that we can not migrate versions (maybe version of database is too old?).");
    
    258
    +        }
    
    250 259
         }
    
    251 260
     
    
    252
    -    public boolean isDbNotVersioned() {
    
    253
    -        return dbNotVersioned;
    
    261
    +    public Path getScriptPath() {
    
    262
    +        return scriptPath;
    
    254 263
         }
    
    255 264
     
    
    256 265
         public Version getModelVersion() {
    
    ... ... @@ -265,35 +274,65 @@ public class TopiaMigrationServiceContext {
    265 274
             return resources;
    
    266 275
         }
    
    267 276
     
    
    268
    -    public void createSchemaIfNotExist() {
    
    277
    +    public boolean adaptVersionTable(TopiaSqlSupport sqlSupport) {
    
    278
    +
    
    279
    +        Version modelVersion = getModelVersion();
    
    280
    +        boolean dbVersionEqualsModelVersion = Objects.equals(dbVersion, modelVersion);
    
    281
    +
    
    269 282
             if (!versionSchemaExist) {
    
    270
    -            sqlHelper.createSchema(jdbcHelper);
    
    271
    -            versionSchemaExist = true;
    
    283
    +            log.info("Create default migration schema.");
    
    284
    +            sqlHelper.createSchema(sqlSupport);
    
    272 285
             }
    
    273
    -    }
    
    274
    -
    
    275
    -    public void createTableIfNotExist() {
    
    276 286
             if (!versionTableExist) {
    
    277
    -            sqlHelper.createTable(jdbcHelper);
    
    278
    -            versionTableExist = true;
    
    287
    +            log.info("Create default migration table.");
    
    288
    +            sqlHelper.createTable(sqlSupport);
    
    289
    +        } else {
    
    290
    +            if (dbVersionEqualsModelVersion) {
    
    291
    +                log.info("Database is up to date, no migration needed.");
    
    292
    +                return false;
    
    293
    +            }
    
    294
    +        }
    
    295
    +        if (legacyVersionTableExist) {
    
    296
    +            log.info("Drop legacy migration table.");
    
    297
    +            MigrationServiceSqlHelper.LEGACY.dropTable(sqlSupport);
    
    298
    +            if (dbVersionEqualsModelVersion) {
    
    299
    +                log.info("Database is up to date (version: {}), but was coming from legacy migration table, fill new migration table.", modelVersion);
    
    300
    +                saveVersion(sqlSupport, modelVersion, null);
    
    301
    +                return false;
    
    302
    +            }
    
    303
    +            log.info("Fill version table {} from legacy table.", dbVersion);
    
    304
    +            saveVersion(sqlSupport, dbVersion, null);
    
    305
    +        } else if (dbNotVersioned) {
    
    306
    +            log.info("Database is empty, no migration needed, set ");
    
    307
    +            saveVersion(sqlSupport, modelVersion, new Date());
    
    308
    +            return false;
    
    279 309
             }
    
    310
    +        // In all other cases, we can try to perform migration
    
    311
    +        return true;
    
    280 312
         }
    
    281 313
     
    
    282
    -    public void saveModelVersion() {
    
    283
    -        saveVersion(null, getModelVersion());
    
    284
    -    }
    
    314
    +    public List<Version> getVersionsToApply() {
    
    285 315
     
    
    286
    -    public Optional<TopiaMigrationServiceAskUserToMigrate> getAskUserToMigrate() {
    
    287
    -        return Optional.ofNullable(configuration.getCallback());
    
    288
    -    }
    
    316
    +        if (versionsToApply.isEmpty()) {
    
    317
    +            log.info("No version to apply, no migration needed.");
    
    318
    +            // No migration, so nothing to save
    
    319
    +//            context.saveModelVersion();
    
    320
    +            return null;
    
    321
    +        }
    
    289 322
     
    
    290
    -    protected void saveVersion(TopiaSqlSupport sqlSupport, Version version) {
    
    291
    -        log.info(String.format("[ Version %s ] Saving new database version.", version));
    
    292
    -        if (sqlSupport != null) {
    
    293
    -            sqlHelper.save(sqlSupport, version.getVersion());
    
    294
    -        } else {
    
    295
    -            sqlHelper.save(jdbcHelper, version.getVersion());
    
    323
    +        // ask to perform the migration
    
    324
    +
    
    325
    +        if (!canApplyMigrationVersions) {
    
    326
    +            // user cancel migration
    
    327
    +            log.warn("Migration was cancelled by migration callback (maybe version of database is too old?).");
    
    328
    +            return null;
    
    296 329
             }
    
    330
    +        return versionsToApply;
    
    331
    +    }
    
    332
    +
    
    333
    +    protected void saveVersion(TopiaSqlSupport sqlSupport, Version version, Date date) {
    
    334
    +        log.info(String.format("[ Version %s ] Saving new database version (date: %s).", version, date));
    
    335
    +        sqlHelper.save(sqlSupport, version.getVersion(), date);
    
    297 336
             dbVersion = version;
    
    298 337
         }
    
    299 338
     
    
    ... ... @@ -309,8 +348,4 @@ public class TopiaMigrationServiceContext {
    309 348
             return new MigrationVersionResourceExecutor(migrationVersionResource, sqlSupport, configuration.getClassifier(), getScriptPath(), migrationVersionResource.getScriptVariables());
    
    310 349
         }
    
    311 350
     
    
    312
    -    public void dropLegacyTable() {
    
    313
    -        MigrationServiceSqlHelper.LEGACY.dropTable(jdbcHelper);
    
    314
    -    }
    
    315
    -
    
    316 351
     }

  • toolkit/persistence/src/main/java/org/nuiton/topia/service/migration/TopiaMigrationServiceImpl.java
    ... ... @@ -34,10 +34,10 @@ import org.nuiton.topia.service.migration.resources.MigrationVersionResource;
    34 34
     import org.nuiton.topia.service.migration.resources.MigrationVersionResourceExecutor;
    
    35 35
     
    
    36 36
     import java.io.IOException;
    
    37
    +import java.util.Date;
    
    37 38
     import java.util.List;
    
    38 39
     import java.util.Map;
    
    39 40
     import java.util.Objects;
    
    40
    -import java.util.Optional;
    
    41 41
     
    
    42 42
     /**
    
    43 43
      * Topia migration service default implementation.
    
    ... ... @@ -68,81 +68,38 @@ public class TopiaMigrationServiceImpl implements TopiaMigrationService {
    68 68
         @Override
    
    69 69
         public void runSchemaMigration() throws TopiaMigrationServiceException {
    
    70 70
     
    
    71
    +        log.info("Migration - Prepare internal states.");
    
    71 72
             TopiaMigrationServiceContext context = TopiaMigrationServiceContext.create(configuration);
    
    72
    -        Version modelVersion = context.getModelVersion();
    
    73
    -        Version dbVersion = context.getDbVersion();
    
    74
    -        boolean dbNotVersioned = context.isDbNotVersioned();
    
    75
    -        boolean legacyVersionTableExist = context.isLegacyVersionTableExist();
    
    76
    -        boolean versionSchemaExist = context.isVersionSchemaExist();
    
    77
    -        boolean versionTableExist = context.isVersionTableExist();
    
    78
    -
    
    79
    -        log.info(String.format("Starting Topia Migration Service  - Model version : %s, Database version : %s", modelVersion, dbVersion));
    
    80
    -
    
    81
    -        if (!versionSchemaExist) {
    
    82
    -            log.info("Create migration schema.");
    
    83
    -            context.createSchemaIfNotExist();
    
    84
    -        }
    
    85
    -        if (!versionTableExist) {
    
    86
    -            log.info("Create migration table.");
    
    87
    -            context.createTableIfNotExist();
    
    88
    -        }
    
    89
    -        if (legacyVersionTableExist) {
    
    90
    -            log.info("Drop legacy migration table.");
    
    91
    -            context.dropLegacyTable();
    
    92
    -            if (dbVersion.equals(modelVersion)) {
    
    93
    -                log.info("Database is up to date, but was coming from legacy migration table, fill new migration table.");
    
    94
    -                context.saveModelVersion();
    
    73
    +        log.info("Migration - Prepare internal states done.");
    
    74
    +
    
    75
    +        try (TopiaPersistenceContext persistenceContext = context.newPersistenceContext()) {
    
    76
    +            log.info("Migration - Adapting migration table.");
    
    77
    +            boolean canContinue = adaptVersionTable(persistenceContext, context);
    
    78
    +            log.info("Migration - Adapting migration table done.");
    
    79
    +            if (!canContinue) {
    
    80
    +                log.info(String.format("Migration - End - db version: %s (nothing more to do).", context.getDbVersion()));
    
    81
    +                return;
    
    82
    +            }
    
    83
    +            log.info("Migration - Getting migration versions to apply.");
    
    84
    +            List<Version> versionsToApply = context.getVersionsToApply();
    
    85
    +            log.info("Migration - Getting migration versions to apply done.");
    
    86
    +            if (versionsToApply == null) {
    
    87
    +                log.info(String.format("Migration - End - db version: %s (nothing more to do).", context.getDbVersion()));
    
    95 88
                     return;
    
    96 89
                 }
    
    97
    -        }
    
    98
    -
    
    99
    -        if (versionTableExist && dbVersion.equals(modelVersion)) {
    
    100
    -            log.info("Database is up to date, no migration needed.");
    
    101
    -            return;
    
    102
    -        }
    
    103
    -
    
    104
    -        if (versionTableExist && dbNotVersioned) {
    
    105
    -            log.info("Database is empty, no migration needed.");
    
    106
    -            context.saveModelVersion();
    
    107
    -            return;
    
    108
    -        }
    
    109
    -
    
    110
    -        List<Version> allVersions = context.getResources().getAvailableVersions();
    
    111
    -        log.info(String.format("Available versions: %1$s", allVersions));
    
    112
    -
    
    113
    -        List<Version> versionsToApply = context.getResources().getVersionsAfter(dbVersion);
    
    114
    -
    
    115
    -        if (versionsToApply.isEmpty()) {
    
    116
    -            log.info("No version to apply, no migration needed.");
    
    117
    -            context.saveModelVersion();
    
    118
    -            return;
    
    119
    -        }
    
    120
    -
    
    121
    -        log.info(String.format("Versions to apply: %1$s", versionsToApply));
    
    122
    -
    
    123
    -        Optional<TopiaMigrationServiceAskUserToMigrate> askUserToMigrate = context.getAskUserToMigrate();
    
    124
    -
    
    125
    -        // ask to perform the migration
    
    126
    -        boolean performMigration = askUserToMigrate.map(c -> c.canIMigrate(dbVersion, versionsToApply)).orElse(true);
    
    127
    -
    
    128
    -        log.debug("Handler choose : " + performMigration);
    
    129 90
     
    
    130
    -        if (!performMigration) {
    
    131
    -            // user cancel migration
    
    132
    -            return;
    
    133
    -        }
    
    91
    +            log.info(String.format("Migration - Will apply versions: %1$s.", versionsToApply));
    
    134 92
     
    
    135
    -        long statementCount = 0;
    
    136
    -        try (TopiaPersistenceContext persistenceContext = context.newPersistenceContext()) {
    
    93
    +            long statementCount = 0;
    
    137 94
                 for (Version version : versionsToApply) {
    
    138 95
                     long t0 = TimeLog.getTime();
    
    139 96
                     long versionCount = migrateVersion(persistenceContext, version, context);
    
    140 97
                     statementCount += versionCount;
    
    141 98
                     TIME_LOG.log(t0, "migrationVersion", version.toString() + " - " + versionCount + " sql statements");
    
    142 99
                 }
    
    100
    +            log.info(String.format("Migration - End - db version: %s - consume %d sql statement(s)", context.getDbVersion(), statementCount));
    
    143 101
             }
    
    144 102
     
    
    145
    -        log.info(String.format("Ends migration - db version: %s - consume %d sql statement(s)", context.getDbVersion(), statementCount));
    
    146 103
         }
    
    147 104
     
    
    148 105
         @Override
    
    ... ... @@ -150,6 +107,17 @@ public class TopiaMigrationServiceImpl implements TopiaMigrationService {
    150 107
             configuration = null;
    
    151 108
         }
    
    152 109
     
    
    110
    +    protected boolean adaptVersionTable(TopiaPersistenceContext persistenceContext, TopiaMigrationServiceContext context) {
    
    111
    +        try {
    
    112
    +            boolean canContinue = context.adaptVersionTable(persistenceContext.getSqlSupport());
    
    113
    +            persistenceContext.commit();
    
    114
    +            return canContinue;
    
    115
    +        } catch (Exception e) {
    
    116
    +            persistenceContext.rollback();
    
    117
    +            throw new TopiaMigrationServiceException("Exception during adapting migration table", e);
    
    118
    +        }
    
    119
    +    }
    
    120
    +
    
    153 121
         protected long migrateVersion(TopiaPersistenceContext persistenceContext, Version version, TopiaMigrationServiceContext context) {
    
    154 122
     
    
    155 123
             MigrationVersionResource resource = context.getResource(version);
    
    ... ... @@ -174,14 +142,15 @@ public class TopiaMigrationServiceImpl implements TopiaMigrationService {
    174 142
                     }
    
    175 143
                 }
    
    176 144
                 // here we use the sqlSupport to save version, to stay on the very same transaction
    
    177
    -            context.saveVersion(sqlSupport, version);
    
    145
    +            context.saveVersion(sqlSupport, version, new Date());
    
    178 146
     
    
    147
    +            // do commit, this migration version is now completed
    
    148
    +            persistenceContext.commit();
    
    179 149
             } catch (Exception e) {
    
    180 150
                 // Exception, rollback transaction
    
    181 151
                 persistenceContext.rollback();
    
    182 152
                 throw new TopiaMigrationServiceException("Exception during schema migration on version: " + version, e);
    
    183 153
             }
    
    184
    -        persistenceContext.commit();
    
    185 154
             return outStatementCount;
    
    186 155
         }
    
    187 156
     
    

  • toolkit/persistence/src/main/java/org/nuiton/topia/service/migration/version/MigrationServiceSqlHelper.java
    ... ... @@ -27,6 +27,10 @@ import org.nuiton.topia.persistence.jdbc.JdbcHelper;
    27 27
     import org.nuiton.topia.persistence.support.TopiaSqlSupport;
    
    28 28
     
    
    29 29
     import java.sql.SQLException;
    
    30
    +import java.sql.Timestamp;
    
    31
    +import java.util.Comparator;
    
    32
    +import java.util.Date;
    
    33
    +import java.util.List;
    
    30 34
     import java.util.Optional;
    
    31 35
     
    
    32 36
     /**
    
    ... ... @@ -38,12 +42,8 @@ import java.util.Optional;
    38 42
      * @since 9.0.7
    
    39 43
      */
    
    40 44
     public interface MigrationServiceSqlHelper {
    
    41
    -    String GET_VERSION_TABLE_STATEMENT = "SELECT version FROM %s;";
    
    42
    -    String CREATE_VERSION_SCHEMA_STATEMENT = "CREATE SCHEMA %s;";
    
    43
    -    String CREATE_VERSION_TABLE_STATEMENT = "CREATE TABLE %s(version VARCHAR(255) NOT NULL, PRIMARY KEY (version));";
    
    44
    -    String DELETE_VERSION_TABLE_STATEMENT = "DELETE FROM %s;";
    
    45
    +    String CREATE_VERSION_SCHEMA_STATEMENT = "CREATE SCHEMA IF NOT EXISTS %s;";
    
    45 46
         String DROP_VERSION_TABLE_STATEMENT = "DROP TABLE %s;";
    
    46
    -    String FILL_VERSION_TABLE_STATEMENT = "INSERT INTO %s(version) VALUES('%s');";
    
    47 47
     
    
    48 48
         /**
    
    49 49
          * Legacy layout.
    
    ... ... @@ -51,6 +51,10 @@ public interface MigrationServiceSqlHelper {
    51 51
         MigrationServiceSqlHelper LEGACY = new MigrationServiceSqlHelper() {
    
    52 52
             public static final String SCHEMA_NAME = "public";
    
    53 53
             public static final String TABLE_NAME = "tms_version";
    
    54
    +        public static final String CREATE_VERSION_TABLE_STATEMENT = "CREATE TABLE %s(version VARCHAR(255) NOT NULL, PRIMARY KEY(version));";
    
    55
    +        public static final String FILL_VERSION_TABLE_STATEMENT = "INSERT INTO %s(version) VALUES('%s');";
    
    56
    +        public static final String GET_VERSION_TABLE_STATEMENT = "SELECT version FROM %s;";
    
    57
    +        public static final String DELETE_VERSION_TABLE_STATEMENT = "DELETE FROM %s;";
    
    54 58
     
    
    55 59
             @Override
    
    56 60
             public String schemaName() {
    
    ... ... @@ -61,15 +65,46 @@ public interface MigrationServiceSqlHelper {
    61 65
             public String tableName() {
    
    62 66
                 return TABLE_NAME;
    
    63 67
             }
    
    68
    +
    
    69
    +        @Override
    
    70
    +        public String createTableSql() {
    
    71
    +            return String.format(CREATE_VERSION_TABLE_STATEMENT, gav());
    
    72
    +        }
    
    73
    +
    
    74
    +        @Override
    
    75
    +        public String getVersionSql() {
    
    76
    +            return String.format(GET_VERSION_TABLE_STATEMENT, gav());
    
    77
    +        }
    
    78
    +
    
    79
    +        @Override
    
    80
    +        public Optional<TMSVersion> getVersion(JdbcHelper jdbcHelper) {
    
    81
    +            try {
    
    82
    +                try {
    
    83
    +                    TMSVersion result = jdbcHelper.runSelect(getVersionSql(), r -> new TMSVersion(r.getString(1), null));
    
    84
    +                    return Optional.ofNullable(result);
    
    85
    +                } catch (Exception e) {
    
    86
    +                    throw new TopiaException("Could not obtain version", e);
    
    87
    +                }
    
    88
    +            } catch (Exception e) {
    
    89
    +                throw new TopiaException("Could not obtain version", e);
    
    90
    +            }
    
    91
    +        }
    
    92
    +
    
    93
    +        @Override
    
    94
    +        public String saveTableSql(String version, Date date) {
    
    95
    +            return String.format(DELETE_VERSION_TABLE_STATEMENT, gav()) + String.format(FILL_VERSION_TABLE_STATEMENT, gav(), version);
    
    96
    +        }
    
    64 97
         };
    
    65 98
         /**
    
    66 99
          * Default layout.
    
    67 100
          */
    
    68 101
         MigrationServiceSqlHelper DEFAULT = new MigrationServiceSqlHelper() {
    
    69
    -        //FIXME Find a better name
    
    70 102
             public static final String SCHEMA_NAME = "common";
    
    71 103
             //FIXME Find a better name
    
    72
    -        public static final String TABLE_NAME = "tms_version";
    
    104
    +        public static final String TABLE_NAME = "database_version";
    
    105
    +        public static final String CREATE_VERSION_TABLE_STATEMENT = "CREATE TABLE %s(version VARCHAR(255) NOT NULL, date TIMESTAMP, PRIMARY KEY(version));";
    
    106
    +        public static final String FILL_VERSION_TABLE_STATEMENT = "INSERT INTO %s(version, date) VALUES('%s', %s);";
    
    107
    +        public static final String GET_VERSION_TABLE_STATEMENT = "SELECT version, date FROM %s;";
    
    73 108
     
    
    74 109
             @Override
    
    75 110
             public String schemaName() {
    
    ... ... @@ -80,6 +115,35 @@ public interface MigrationServiceSqlHelper {
    80 115
             public String tableName() {
    
    81 116
                 return TABLE_NAME;
    
    82 117
             }
    
    118
    +
    
    119
    +        @Override
    
    120
    +        public String createTableSql() {
    
    121
    +            return String.format(CREATE_VERSION_TABLE_STATEMENT, gav());
    
    122
    +        }
    
    123
    +
    
    124
    +        @Override
    
    125
    +        public String getVersionSql() {
    
    126
    +            return String.format(GET_VERSION_TABLE_STATEMENT, gav());
    
    127
    +        }
    
    128
    +
    
    129
    +        @Override
    
    130
    +        public Optional<TMSVersion> getVersion(JdbcHelper jdbcHelper) {
    
    131
    +            try {
    
    132
    +                List<TMSVersion> result = jdbcHelper.runMultipleSelect(getVersionSql(), r -> new TMSVersion(r.getString(1), r.getTimestamp(2)));
    
    133
    +                if (result.isEmpty()) {
    
    134
    +                    return Optional.empty();
    
    135
    +                }
    
    136
    +                result.sort(Comparator.comparing(TMSVersion::getVersion).reversed());
    
    137
    +                return Optional.of(result.get(0));
    
    138
    +            } catch (Exception e) {
    
    139
    +                throw new TopiaException("Could not obtain version", e);
    
    140
    +            }
    
    141
    +        }
    
    142
    +
    
    143
    +        @Override
    
    144
    +        public String saveTableSql(String version, Date date) {
    
    145
    +            return String.format(FILL_VERSION_TABLE_STATEMENT, gav(), version, date == null ? "NULL" : ("'" + new Timestamp(date.getTime()) + "'::timestamp"));
    
    146
    +        }
    
    83 147
         };
    
    84 148
     
    
    85 149
         /**
    
    ... ... @@ -89,7 +153,7 @@ public interface MigrationServiceSqlHelper {
    89 153
          * <p>
    
    90 154
          * We will need even after that to keep the legacy definition, to be able to migration older database using it.
    
    91 155
          */
    
    92
    -    MigrationServiceSqlHelper CURRENT = LEGACY;
    
    156
    +    MigrationServiceSqlHelper CURRENT = DEFAULT;
    
    93 157
     
    
    94 158
         static boolean isLegacy() {
    
    95 159
             return CURRENT.equals(LEGACY);
    
    ... ... @@ -112,59 +176,22 @@ public interface MigrationServiceSqlHelper {
    112 176
             return schemaName() + "." + tableName();
    
    113 177
         }
    
    114 178
     
    
    115
    -    default Optional<TMSVersion> getVersion(JdbcHelper jdbcHelper) {
    
    116
    -        try {
    
    117
    -            String version = jdbcHelper.runSelectOnString(getVersionSql());
    
    118
    -            return Optional.ofNullable(version == null ? null : new TMSVersion(version));
    
    119
    -        } catch (Exception e) {
    
    120
    -            throw new TopiaException("Could not obtain version", e);
    
    121
    -        }
    
    122
    -    }
    
    123
    -
    
    124
    -    default String getVersionSql() {
    
    125
    -        return String.format(GET_VERSION_TABLE_STATEMENT, gav());
    
    126
    -    }
    
    179
    +    Optional<TMSVersion> getVersion(JdbcHelper jdbcHelper);
    
    127 180
     
    
    128
    -    default String createSchemaSql() {
    
    129
    -        return String.format(CREATE_VERSION_SCHEMA_STATEMENT, gav());
    
    130
    -    }
    
    181
    +    String getVersionSql();
    
    131 182
     
    
    132
    -    default String createTableSql() {
    
    133
    -        return String.format(CREATE_VERSION_TABLE_STATEMENT, gav());
    
    134
    -    }
    
    183
    +    String createTableSql();
    
    135 184
     
    
    136
    -    default String deleteTableSql() {
    
    137
    -        return String.format(DELETE_VERSION_TABLE_STATEMENT, gav());
    
    138
    -    }
    
    185
    +    String saveTableSql(String version, Date date);
    
    139 186
     
    
    140
    -    default String fillVersionSql(String version) {
    
    141
    -        return String.format(FILL_VERSION_TABLE_STATEMENT, gav(), version);
    
    187
    +    default String createSchemaSql() {
    
    188
    +        return String.format(CREATE_VERSION_SCHEMA_STATEMENT, schemaName());
    
    142 189
         }
    
    143 190
     
    
    144 191
         default String dropTableSql() {
    
    145 192
             return String.format(DROP_VERSION_TABLE_STATEMENT, gav());
    
    146 193
         }
    
    147 194
     
    
    148
    -    default String saveTableSql(String version) {
    
    149
    -        return deleteTableSql() + fillVersionSql(version);
    
    150
    -    }
    
    151
    -
    
    152
    -    default void save(JdbcHelper jdbcHelper, String version) {
    
    153
    -        try {
    
    154
    -            jdbcHelper.runUpdate(saveTableSql(version));
    
    155
    -        } catch (Exception e) {
    
    156
    -            throw new TopiaException(String.format("Could not save version %s", version), e);
    
    157
    -        }
    
    158
    -    }
    
    159
    -
    
    160
    -    default void save(TopiaSqlSupport sqlSupport, String version) {
    
    161
    -        try {
    
    162
    -            sqlSupport.executeSql(saveTableSql(version));
    
    163
    -        } catch (Exception e) {
    
    164
    -            throw new TopiaException(String.format("Could not save version %s", version), e);
    
    165
    -        }
    
    166
    -    }
    
    167
    -
    
    168 195
         default boolean isTableExist(JdbcHelper jdbcHelper) {
    
    169 196
             try {
    
    170 197
                 return jdbcHelper.isTableExist(schemaName(), tableName());
    
    ... ... @@ -181,27 +208,35 @@ public interface MigrationServiceSqlHelper {
    181 208
             }
    
    182 209
         }
    
    183 210
     
    
    184
    -    default void createSchema(JdbcHelper jdbcHelper) {
    
    211
    +    default void createSchema(TopiaSqlSupport sqlSupport) {
    
    185 212
             try {
    
    186
    -            jdbcHelper.runUpdate(createSchemaSql());
    
    213
    +            sqlSupport.executeSql(createSchemaSql());
    
    187 214
             } catch (Exception e) {
    
    188
    -            throw new TopiaException(String.format("Could not create version table %s", gav()), e);
    
    215
    +            throw new TopiaException(String.format("Could not create version schema %s", gav()), e);
    
    189 216
             }
    
    190 217
         }
    
    191 218
     
    
    192
    -    default void createTable(JdbcHelper jdbcHelper) {
    
    219
    +    default void createTable(TopiaSqlSupport sqlSupport) {
    
    193 220
             try {
    
    194
    -            jdbcHelper.runUpdate(createTableSql());
    
    221
    +            sqlSupport.executeSql(createTableSql());
    
    195 222
             } catch (Exception e) {
    
    196 223
                 throw new TopiaException(String.format("Could not create version table %s", gav()), e);
    
    197 224
             }
    
    198 225
         }
    
    199 226
     
    
    200
    -    default void dropTable(JdbcHelper jdbcHelper) {
    
    227
    +    default void dropTable(TopiaSqlSupport sqlSupport) {
    
    201 228
             try {
    
    202
    -            jdbcHelper.runUpdate(dropTableSql());
    
    229
    +            sqlSupport.executeSql(dropTableSql());
    
    203 230
             } catch (Exception e) {
    
    204 231
                 throw new TopiaException(String.format("Could not drop version table %s", gav()), e);
    
    205 232
             }
    
    206 233
         }
    
    234
    +
    
    235
    +    default void save(TopiaSqlSupport sqlSupport, String version, Date date) {
    
    236
    +        try {
    
    237
    +            sqlSupport.executeSql(saveTableSql(version, date));
    
    238
    +        } catch (Exception e) {
    
    239
    +            throw new TopiaException(String.format("Could not save version %s", version), e);
    
    240
    +        }
    
    241
    +    }
    
    207 242
     }

  • toolkit/persistence/src/main/java/org/nuiton/topia/service/migration/version/TMSVersion.java
    ... ... @@ -25,6 +25,7 @@ package org.nuiton.topia.service.migration.version;
    25 25
     import io.ultreia.java4all.util.Version;
    
    26 26
     
    
    27 27
     import java.io.Serializable;
    
    28
    +import java.util.Date;
    
    28 29
     
    
    29 30
     /**
    
    30 31
      * @author Tony Chemit - dev@tchemit.fr
    
    ... ... @@ -33,27 +34,23 @@ public class TMSVersion implements Serializable {
    33 34
     
    
    34 35
         private static final long serialVersionUID = 1L;
    
    35 36
     
    
    36
    -    private String version;
    
    37
    +    private final Version version;
    
    38
    +    private final Date date;
    
    37 39
     
    
    38
    -    public TMSVersion() {
    
    39
    -    }
    
    40
    -
    
    41
    -    public TMSVersion(String version) {
    
    40
    +    public TMSVersion(String version, Date date) {
    
    42 41
             if (version == null || version.isEmpty()) {
    
    43 42
                 throw new IllegalArgumentException("version parameter can not be null nor empty.");
    
    44 43
             }
    
    45
    -        this.version = version;
    
    44
    +        this.version = Version.valueOf(version);
    
    45
    +        this.date = date;
    
    46 46
         }
    
    47 47
     
    
    48
    -    public String getVersion() {
    
    48
    +    public Version getVersion() {
    
    49 49
             return version;
    
    50 50
         }
    
    51 51
     
    
    52
    -    public void setVersion(String version) {
    
    53
    -        this.version = version;
    
    52
    +    public Date getDate() {
    
    53
    +        return date;
    
    54 54
         }
    
    55 55
     
    
    56
    -    public Version toVersion() {
    
    57
    -        return version == null || version.isEmpty() ? null : Version.valueOf(version);
    
    58
    -    }
    
    59 56
     }

  • toolkit/persistence/src/main/java/org/nuiton/topia/service/sql/internal/consumer/AddVersionTableConsumer.java
    ... ... @@ -29,6 +29,8 @@ import org.nuiton.topia.service.sql.internal.SqlRequestConsumer;
    29 29
     import org.nuiton.topia.service.sql.internal.SqlRequestSetConsumerContext;
    
    30 30
     import org.nuiton.topia.service.sql.internal.request.AddVersionTableRequest;
    
    31 31
     
    
    32
    +import java.util.Date;
    
    33
    +
    
    32 34
     /**
    
    33 35
      * Created on 21/02/2021.
    
    34 36
      *
    
    ... ... @@ -41,8 +43,9 @@ public class AddVersionTableConsumer implements SqlRequestConsumer<AddVersionTab
    41 43
         public void consume(AddVersionTableRequest request, SqlRequestSetConsumerContext context) {
    
    42 44
             try {
    
    43 45
                 SqlScriptWriter writer = context.getWriter();
    
    46
    +            writer.writeSql(MigrationServiceSqlHelper.CURRENT.createSchemaSql());
    
    44 47
                 writer.writeSql(MigrationServiceSqlHelper.CURRENT.createTableSql());
    
    45
    -            writer.writeSql(MigrationServiceSqlHelper.CURRENT.fillVersionSql(request.getDbVersion().getVersion()));
    
    48
    +            writer.writeSql(MigrationServiceSqlHelper.CURRENT.saveTableSql(request.getDbVersion().getVersion(), new Date()));
    
    46 49
             } catch (Exception e) {
    
    47 50
                 throw new TopiaException(String.format("Could not add version table for reason: %s", e.getMessage()), e);
    
    48 51
             }