DEV Community

iron_man
iron_man

Posted on

Scan2

public Snapshot scan(String run, Target target, List entries) {
String targetSchema = schema(target);

try (Connection targetConnection = factory.open(targetSchema, target.alias())) {
    List<ObjectInfo> objects = new ArrayList<>();

    // Bulk query 1: errors for all invalid objects.
    Map<String, List<String>> errorsByObject = new HashMap<>();

    try (PreparedStatement s = targetConnection.prepareStatement(
            "SELECT e.NAME, e.TYPE, e.LINE, e.POSITION, e.TEXT " +
            "FROM USER_ERRORS e JOIN USER_OBJECTS o " +
            "ON o.OBJECT_NAME = e.NAME AND o.OBJECT_TYPE = e.TYPE " +
            "WHERE o.STATUS = 'INVALID' " +
            "ORDER BY e.NAME, e.TYPE, e.SEQUENCE")) {

        s.setQueryTimeout(20);

        try (ResultSet r = s.executeQuery()) {
            while (r.next()) {
                String key = r.getString(1) + "\u0000" + r.getString(2);

                errorsByObject
                        .computeIfAbsent(key, ignored -> new ArrayList<>())
                        .add("Line " + r.getInt(3) + ":" +
                                r.getInt(4) + " " + r.getString(5));
            }
        }
    }

    // Bulk query 2: dependencies for all invalid objects.
    Map<String, List<String>> dependenciesByObject = new HashMap<>();

    try (PreparedStatement s = targetConnection.prepareStatement(
            "SELECT d.NAME, d.TYPE, d.REFERENCED_NAME " +
            "FROM USER_DEPENDENCIES d JOIN USER_OBJECTS o " +
            "ON o.OBJECT_NAME = d.NAME AND o.OBJECT_TYPE = d.TYPE " +
            "WHERE o.STATUS = 'INVALID' " +
            "AND d.REFERENCED_OWNER = USER " +
            "ORDER BY d.NAME, d.TYPE, d.REFERENCED_NAME")) {

        s.setQueryTimeout(20);

        try (ResultSet r = s.executeQuery()) {
            while (r.next()) {
                String key = r.getString(1) + "\u0000" + r.getString(2);

                dependenciesByObject
                        .computeIfAbsent(key, ignored -> new ArrayList<>())
                        .add(r.getString(3));
            }
        }
    }

    // Bulk query 3: all invalid object names and types.
    try (PreparedStatement s = targetConnection.prepareStatement(
            "SELECT OBJECT_NAME, OBJECT_TYPE FROM USER_OBJECTS " +
            "WHERE STATUS = 'INVALID' " +
            "ORDER BY OBJECT_TYPE, OBJECT_NAME")) {

        s.setQueryTimeout(20);

        try (ResultSet r = s.executeQuery()) {
            while (r.next()) {
                String name = r.getString(1);
                String type = r.getString(2);
                String key = name + "\u0000" + type;

                objects.add(new ObjectInfo(
                        name,
                        type,
                        "INVALID",
                        errorsByObject.getOrDefault(key, List.of()),
                        dependenciesByObject.getOrDefault(key, List.of())
                ));
            }
        }
    }

    // Reuse one Oracle connection per execution schema.
    Map<String, Connection> connections = new HashMap<>();
    connections.put(targetSchema, targetConnection);

    Set<String> satisfied = new HashSet<>();

    try {
        for (LibraryEntry entry : entries) {
            String segment = entry.executionSegment().equals("CURRENT")
                    ? target.segment()
                    : entry.executionSegment();

            String executionSchema = names.build(
                    SchemaInputParser.parse(target.input()).base(),
                    segment
            );

            Connection checkConnection = connections.get(executionSchema);

            if (checkConnection == null) {
                checkConnection = factory.open(executionSchema, target.alias());
                connections.put(executionSchema, checkConnection);
            }

            if (check(checkConnection, entry, target)) {
                satisfied.add(entry.id());
            }
        }
    } finally {
        for (Connection connection : connections.values()) {
            if (connection != targetConnection) {
                try {
                    connection.close();
                } catch (SQLException ignored) {
                }
            }
        }
    }

    return new Snapshot(objects, satisfied);

} catch (SQLException e) {
    throw databaseError(e);
}
Enter fullscreen mode Exit fullscreen mode

}

Top comments (0)