Skip to content

Commit

Permalink
Add a task for refreshing the materialized views
Browse files Browse the repository at this point in the history
  • Loading branch information
bchapuis committed Jan 13, 2025
1 parent 7e96e34 commit c8e6f65
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.baremaps.tasks;

import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.baremaps.postgres.graph.DatabaseMetadataRetriever;
import org.apache.baremaps.postgres.graph.DependencyGraphBuilder;
import org.apache.baremaps.postgres.graph.MaterializedViewRefresher;
import org.apache.baremaps.workflow.Task;
import org.apache.baremaps.workflow.WorkflowContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RefreshMaterializedViews implements Task {

private static final Logger LOGGER = LoggerFactory.getLogger(RefreshMaterializedViews.class);

private Object database;

public RefreshMaterializedViews() {
// Default constructor
}

public RefreshMaterializedViews(Object database) {
this.database = database;
}

@Override
public void execute(WorkflowContext context) throws Exception {
DataSource dataSource = context.getDataSource(database);
try (var connection = dataSource.getConnection()) {
LOGGER.info("Connected to PostgreSQL database.");
var schema = "public";

// 1. Retrieve database objects (tables, views, materialized views).
var objects = DatabaseMetadataRetriever.getObjects(connection, schema);

// 2. Retrieve dependencies between database objects.
var dependencies = DatabaseMetadataRetriever.getDependencies(connection, schema, objects);

// 3. Build a directed graph of dependencies between the database objects.
var graph = DependencyGraphBuilder.buildGraph(connection, schema, objects, dependencies);

// 4. Perform a topological sort so that dependencies come before dependents.
var sorted = DependencyGraphBuilder.topologicalSort(graph);

// 5. Refresh materialized views, dropping and recreating indexes if present.
MaterializedViewRefresher.refreshMaterializedViews(connection, sorted);

LOGGER.info("Done refreshing materialized views.");
} catch (SQLException ex) {
LOGGER.error("Database error", ex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
@Type(value = ImportOsmPbf.class, name = "ImportOsmPbf"),
@Type(value = ImportShapefile.class, name = "ImportShapefile"),
@Type(value = LogMessage.class, name = "LogMessage"),
@Type(value = RefreshMaterializedViews.class, name = "RefreshMaterializedViews"),
@Type(value = UpdateOsmDatabase.class, name = "UpdateOsmDatabase"),
})
public interface Task {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
/**
* Utility class to retrieve metadata about tables, views, and materialized views.
*/
class DatabaseMetadataRetriever {
public class DatabaseMetadataRetriever {

private static final Logger LOGGER =
LoggerFactory.getLogger(DatabaseMetadataRetriever.class.getName());
Expand Down Expand Up @@ -208,15 +208,15 @@ public record DatabaseObject(
/**
* Record representing a dependency between two database objects.
*/
record DatabaseDependency(DatabaseObject source, DatabaseObject dependent) {
public record DatabaseDependency(DatabaseObject source, DatabaseObject dependent) {

}


/**
* Record representing a database index.
*/
record DatabaseIndex(String indexName, String indexDef) {
public record DatabaseIndex(String indexName, String indexDef) {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
/**
* Utility class to build a directed dependency graph among DatabaseObject items.
*/
class DependencyGraphBuilder {
public class DependencyGraphBuilder {

private static final Logger LOGGER =
LoggerFactory.getLogger(DependencyGraphBuilder.class.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* Utility class to refresh materialized views in topological order: 1) drop indexes, 2) refresh MV,
* 3) recreate indexes.
*/
class MaterializedViewRefresher {
public class MaterializedViewRefresher {

private static final Logger LOGGER =
LoggerFactory.getLogger(MaterializedViewRefresher.class.getName());
Expand Down
26 changes: 5 additions & 21 deletions basemap/refresh.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,14 @@ import config from "./config.js";
export default {
"steps": [
{
"id": "refresh-node",
"id": "refresh-materialized-views",
"needs": [],
"tasks": [
"layers/node/refresh.sql",
"layers/way/refresh.sql",
"layers/relation/refresh.sql",
"layers/member/refresh.sql",
"layers/amenity/refresh.sql",
"layers/ocean/refresh.sql",
"layers/highway/refresh.sql",
"layers/landuse/refresh.sql",
"layers/leisure/refresh.sql",
"layers/natural/refresh.sql",
"layers/point/refresh.sql",
"layers/railway/refresh.sql",
"layers/route/refresh.sql",
"layers/waterway/refresh.sql"
].map(file => {
return {
"type": "ExecuteSql",
"file": file,
{
"type": "RefreshMaterializedViews",
"database": config.database,
}
})
},
]
}
]
}

0 comments on commit c8e6f65

Please sign in to comment.