simplify vehicle identity binding to plate vin
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled

This commit is contained in:
lingniu
2026-06-29 23:07:25 +08:00
parent 6a17134942
commit 1682b3f83f
5 changed files with 135 additions and 83 deletions

View File

@@ -47,9 +47,7 @@ public final class MySqlVehicleIdentityService implements VehicleIdentityResolve
if (binding == null || !binding.hasResolvedVin()) {
return;
}
upsert(binding.protocol(), "PHONE", binding.phone(), binding.vin());
upsert(binding.protocol(), "DEVICE_ID", binding.deviceId(), binding.vin());
upsert(binding.protocol(), "PLATE", binding.plate(), binding.vin());
upsert(binding.plate(), binding.vin());
index.bind(binding);
}
@@ -91,13 +89,9 @@ public final class MySqlVehicleIdentityService implements VehicleIdentityResolve
private void initializeSchema() {
String sql = """
CREATE TABLE IF NOT EXISTS %s (
protocol VARCHAR(32) NOT NULL,
identifier_type VARCHAR(32) NOT NULL,
identifier_value VARCHAR(128) NOT NULL,
plate VARCHAR(128) NOT NULL,
vin VARCHAR(64) NOT NULL,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (protocol, identifier_type, identifier_value),
PRIMARY KEY (plate),
KEY idx_vehicle_identity_vin (vin)
)
""".formatted(table);
@@ -132,17 +126,17 @@ public final class MySqlVehicleIdentityService implements VehicleIdentityResolve
private InMemoryVehicleIdentityService loadIndex() {
InMemoryVehicleIdentityService loaded = new InMemoryVehicleIdentityService();
String sql = "SELECT protocol, identifier_type, identifier_value, vin FROM " + table;
String sql = "SELECT plate, vin FROM " + table;
try (Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(sql);
ResultSet resultSet = statement.executeQuery()) {
while (resultSet.next()) {
bindLoadedRow(
loaded,
protocol(resultSet.getString("protocol")),
resultSet.getString("identifier_type"),
resultSet.getString("identifier_value"),
resultSet.getString("vin"));
loaded.bind(new VehicleIdentityBinding(
ProtocolId.JT808,
resultSet.getString("vin"),
"",
"",
resultSet.getString("plate")));
}
loadRegistrationIndex(loaded, connection);
return loaded;
@@ -152,6 +146,24 @@ public final class MySqlVehicleIdentityService implements VehicleIdentityResolve
}
private void loadRegistrationIndex(InMemoryVehicleIdentityService loaded, Connection connection) throws SQLException {
String sql = "SELECT r.protocol, r.phone, r.device_id, r.plate, b.vin FROM " + registrationTable + " r "
+ "JOIN " + table + " b ON b.plate = r.plate "
+ "WHERE b.vin IS NOT NULL AND b.vin <> '' AND LOWER(b.vin) <> 'unknown'";
try (PreparedStatement statement = connection.prepareStatement(sql);
ResultSet resultSet = statement.executeQuery()) {
while (resultSet.next()) {
loaded.bind(new VehicleIdentityBinding(
protocol(resultSet.getString("protocol")),
resultSet.getString("vin"),
resultSet.getString("phone"),
resultSet.getString("device_id"),
resultSet.getString("plate")));
}
}
loadLegacyRegistrationVinIndex(loaded, connection);
}
private void loadLegacyRegistrationVinIndex(InMemoryVehicleIdentityService loaded, Connection connection) throws SQLException {
String sql = "SELECT protocol, phone, device_id, plate, vin FROM " + registrationTable
+ " WHERE vin IS NOT NULL AND vin <> '' AND LOWER(vin) <> 'unknown'";
try (PreparedStatement statement = connection.prepareStatement(sql);
@@ -167,26 +179,6 @@ public final class MySqlVehicleIdentityService implements VehicleIdentityResolve
}
}
private void bindLoadedRow(InMemoryVehicleIdentityService loaded,
ProtocolId protocol,
String identifierType,
String identifierValue,
String vin) {
if (vin == null || vin.isBlank()) {
return;
}
String type = identifierType == null ? "" : identifierType.trim().toUpperCase(Locale.ROOT);
VehicleIdentityBinding binding = switch (type) {
case "PHONE" -> new VehicleIdentityBinding(protocol, vin, identifierValue, "", "");
case "DEVICE_ID" -> new VehicleIdentityBinding(protocol, vin, "", identifierValue, "");
case "PLATE" -> new VehicleIdentityBinding(protocol, vin, "", "", identifierValue);
default -> null;
};
if (binding != null) {
loaded.bind(binding);
}
}
private ScheduledExecutorService startRefresher(Duration refreshInterval) {
if (refreshInterval == null || refreshInterval.isZero() || refreshInterval.isNegative()) {
return null;
@@ -209,20 +201,18 @@ public final class MySqlVehicleIdentityService implements VehicleIdentityResolve
}
}
private void upsert(ProtocolId protocol, String identifierType, String identifierValue, String vin) {
String normalizedIdentifier = normalize(identifierValue);
if (normalizedIdentifier.isBlank()) {
private void upsert(String plate, String vin) {
String normalizedPlate = normalize(plate);
if (normalizedPlate.isBlank()) {
return;
}
String sql = "INSERT INTO " + table + " (protocol, identifier_type, identifier_value, vin) "
+ "VALUES (?, ?, ?, ?) "
+ "ON DUPLICATE KEY UPDATE vin = VALUES(vin), updated_at = CURRENT_TIMESTAMP";
String sql = "INSERT INTO " + table + " (plate, vin) "
+ "VALUES (?, ?) "
+ "ON DUPLICATE KEY UPDATE vin = VALUES(vin)";
try (Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setString(1, protocolName(protocol));
statement.setString(2, identifierType);
statement.setString(3, normalizedIdentifier);
statement.setString(4, vin.trim());
statement.setString(1, normalizedPlate);
statement.setString(2, vin.trim());
statement.executeUpdate();
} catch (SQLException e) {
throw new IllegalStateException("vehicle identity mysql bind failed: " + table, e);