package com.mydreamjob.job; import com.mydreamjob.config.MySql57MigrationConfiguration; import org.flywaydb.core.Flyway; import org.junit.jupiter.api.Test; import org.testcontainers.containers.MySQLContainer; import java.sql.*; import java.util.*; import static org.junit.jupiter.api.Assertions.*; /** 独立 V59→V60:真实 MySQL 两版本,旧地址保留、六列、精度、历史 checksum 和幂等。 */ class JobMapLocationMySqlMigrationTest { @Test void mysql57V59ToV60() throws Exception { verify("mysql:5.7.36"); } @Test void mysql8V59ToV60() throws Exception { verify("mysql:8.4"); } private Flyway flyway(MySQLContainer db,String version) { var config=Flyway.configure().dataSource(db.getJdbcUrl(),db.getUsername(),db.getPassword()) .locations("classpath:db/migration").target(version); MySql57MigrationConfiguration.configure(config); return config.load(); } private void verify(String image) throws Exception { try(var db=new MySQLContainer<>(image).withDatabaseName("job_map_migration") .withUsername("maptest").withPassword("synthetic-test-only") .withUrlParam("characterEncoding","UTF-8") .withCreateContainerCmdModifier(c->c.getHostConfig().withMemory(768L*1024*1024))) { db.start(); try(var c=DriverManager.getConnection(db.getJdbcUrl(),db.getUsername(),db.getPassword());var s=c.createStatement()) { s.execute("ALTER DATABASE job_map_migration CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); flyway(db,"59").migrate(); List history=history(s); s.execute("INSERT INTO users(id,phone,role,is_active,is_verified) VALUES(930001,'19900889999','COMPANY',1,1)"); s.execute("INSERT INTO companies(id,owner_user_id,name,verified) VALUES(930001,930001,'位置迁移测试企业',1)"); s.execute("INSERT INTO jobs(id,company_id,title,description,city,employment_type,status,work_location) " +"VALUES(930001,930001,'迁移测试岗位','合成数据','北京','FULL_TIME','DRAFT','旧工作地址')"); assertEquals(1,flyway(db,"60").migrate().migrationsExecuted); assertEquals(history,history(s)); try(var r=s.executeQuery("SELECT work_location,map_location_status,map_longitude,map_latitude,map_poi_name FROM jobs WHERE id=930001")) { assertTrue(r.next());assertEquals("旧工作地址",r.getString(1));assertEquals("UNSET",r.getString(2)); assertNull(r.getBigDecimal(3));assertNull(r.getBigDecimal(4));assertNull(r.getString(5)); } try(var r=s.executeQuery("SELECT count(*) FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='jobs' " +"AND column_name IN ('map_longitude','map_latitude','map_coordinate_system','map_location_status','map_poi_id','map_poi_name')")) { assertTrue(r.next());assertEquals(6,r.getInt(1)); } s.executeUpdate("UPDATE jobs SET map_longitude=116.397463,map_latitude=39.909187,map_coordinate_system='GCJ02'," +"map_location_status='CONFIRMED',map_poi_id='test-poi',map_poi_name='公开地标' WHERE id=930001"); try(var r=s.executeQuery("SELECT map_longitude,map_latitude FROM jobs WHERE id=930001")) { assertTrue(r.next());assertEquals("116.397463",r.getBigDecimal(1).toPlainString()); assertEquals("39.909187",r.getBigDecimal(2).toPlainString()); } assertEquals(0,flyway(db,"60").migrate().migrationsExecuted);flyway(db,"60").validate(); assertEquals(history,history(s)); } } } private List history(Statement s) throws SQLException { var rows=new ArrayList(); try(var r=s.executeQuery("SELECT version,checksum,success FROM flyway_schema_history WHERE version<>'60' ORDER BY installed_rank")) { while(r.next())rows.add(r.getString(1)+"|"+r.getString(2)+"|"+r.getBoolean(3)); } return rows; } }