Skip to content

Commit

Permalink
Merge pull request #248 from AdaptiveScale/release-2.5.2
Browse files Browse the repository at this point in the history
Release 2.5.2
  • Loading branch information
nbesimi authored Aug 28, 2024
2 parents 2c25dc1 + 2a47b7b commit a5a3787
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 50 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repositories {

allprojects {
group = 'com.adaptivescale'
version = '2.5.1'
version = '2.5.2'
sourceCompatibility = 11
targetCompatibility = 11
}
Expand Down
2 changes: 1 addition & 1 deletion cli/src/main/java/com/adaptivescale/rosetta/cli/Cli.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
@Slf4j
@CommandLine.Command(name = "cli",
mixinStandardHelpOptions = true,
version = "2.5.1",
version = "2.5.2",
description = "Declarative Database Management - DDL Transpiler"
)
class Cli implements Callable<Void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ public String createDatabase(Database database, boolean dropTableIfExists) {
.map(table -> createTable(table, dropTableIfExists))
.collect(Collectors.joining("\r\r")));

stringBuilder.append(database.getViews()
.stream()
.map(view -> createView(view, dropTableIfExists))
.collect(Collectors.joining("\r\r")));

//TODO: Check if we can enable foreign keys in Kinetica
//Disable temporarily the foreign keys in Kinetica
// String foreignKeys = database
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,78 +17,67 @@
package com.adataptivescale.rosetta.source.core.extractors.view;

import com.adaptivescale.rosetta.common.annotations.RosettaModule;
import com.adaptivescale.rosetta.common.models.Table;
import com.adaptivescale.rosetta.common.models.View;
import com.adaptivescale.rosetta.common.types.RosettaModuleTypes;
import com.adataptivescale.rosetta.source.common.QueryHelper;
import lombok.extern.slf4j.Slf4j;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@RosettaModule(
name = "kinetica",
type = RosettaModuleTypes.VIEW_EXTRACTOR
)
public class KineticaViewExtractor extends DefaultViewExtractor{
@Slf4j
@RosettaModule(name = "kinetica", type = RosettaModuleTypes.VIEW_EXTRACTOR)
public class KineticaViewExtractor extends DefaultViewExtractor {
@Override
protected void attachViewDDL(Collection<View> views, java.sql.Connection connection) throws SQLException {
HashMap<String, List<View>> viewsBySchema = new HashMap<>();
for (View view : views) {
viewsBySchema.computeIfAbsent(view.getSchema(), k->new ArrayList<View>()).add(view);
protected void attachViewDDL(Collection<View> views, java.sql.Connection connection) {
if (views.isEmpty()) {
return;
}

//Logical Views
processViews(connection, viewsBySchema,
"select * from information_schema.VIEWS where TABLE_SCHEMA='%s'",
"table_name",
"view_definition",
false);
List<String> schemaList = views.stream()
.map(Table::getSchema)
.map(schema -> "'" + schema + "'") // Wrap each string in single quotes
.collect(Collectors.toList());

//Materialized views
processViews(connection, viewsBySchema,
"select * from pg_catalog.pg_matviews where schemaname='%s'",
"matviewname",
"definition",
true);
}
// Fetch view info only (M is for Materialized, V is Logical view)
String queryTemplate = "SELECT object_name, schema_name, shard_kind, persistence, obj_kind, definition " +
"FROM ki_catalog.ki_objects " +
"WHERE schema_name IN (%s) AND obj_kind in ('V', 'M')";

private void processViews(java.sql.Connection connection, HashMap<String, List<View>> viewsBySchema,
String queryTemplate, String nameField, String ddlField,
boolean isMaterialized) throws SQLException {
for (String schemaName : viewsBySchema.keySet()) {
Statement statement = connection.createStatement();
String query = String.format(queryTemplate, schemaName);
try (Statement statement = connection.createStatement()) {
String query = String.format(queryTemplate, String.join(", ", schemaList));
ResultSet resultSet = statement.executeQuery(query);
List<Map<String, Object>> records = QueryHelper.mapRecords(resultSet);
for (Map<String, Object> record : records) {
Optional<View> tmpTable = viewsBySchema.get(schemaName).stream()
.filter(view -> view.getName().equals(record.get(nameField))).findAny();
if (tmpTable.isPresent()) {
String finalDdl = processDDL(record.get(ddlField).toString());
tmpTable.get().setCode(finalDdl);
if (isMaterialized) {
tmpTable.get().setMaterialized(true);

for (View view : views) {
Optional<Map<String, Object>> record = records.stream().filter(rec -> view.getName().equals(rec.get("object_name")) && view.getSchema().equals(rec.get("schema_name"))).findAny();

if (record.isPresent()) {
view.setCode(record.get().get("definition").toString());
if (record.get().get("obj_kind").equals("M")) {
view.setMaterialized(true);
}
}
}
}
}

private String processDDL(String ddl) {
String[] ddls = ddl.split("\n");
String processedDdl = Arrays.stream(Arrays.copyOfRange(ddls, 1, ddls.length))
.collect(Collectors.joining(" "));
if (processedDdl.endsWith(";")) {
processedDdl = processedDdl.substring(0, processedDdl.length() - 2);
} catch (SQLException e) {
log.warn("Skipping processing views due to error: {}", e.getMessage());
}
return processedDdl.replaceAll("\\s+", " ").trim();

// Skip view due to incomplete code, safety issue
views.removeIf(view -> {
if (view.getCode() == null || view.getCode().isEmpty() || view.getCode().length() == 256) {
log.warn("Skipping view due to incomplete code: {}.{}", view.getSchema(), view.getName());
return true;
}
return false;
});
}
}

0 comments on commit a5a3787

Please sign in to comment.