Skip to content

Commit

Permalink
avniproject#762 | MCI and MQB added and others modified
Browse files Browse the repository at this point in the history
  • Loading branch information
nthapa000 committed Sep 5, 2024
1 parent dac5397 commit b2604a0
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 127 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.avni.server.domain.metabase.*;
import org.avni.server.util.S;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Repository;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -24,26 +26,99 @@ public Database save(Database database) {
return database;
}

public MetabaseDatabaseInfo getDatabaseDetails(int databaseId) {
String url = metabaseApiUrl + "/database/" + databaseId + "?include=tables";
public Database getDatabaseByName(String databaseName) {
String url = metabaseApiUrl + "/database";
String jsonResponse = getForObject(url, String.class);
try {
List<Database> databases = objectMapper.readValue(jsonResponse, new TypeReference<List<Database>>() {});
return databases.stream()
.filter(db -> db.getName().equals(databaseName))
.findFirst()
.orElseThrow(() -> new RuntimeException("Database with name " + databaseName + " not found."));
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve database", e);
}
}

public MetabaseCollectionInfo getCollectionByName(String collectionName) {
String url = metabaseApiUrl + "/collection";
String jsonResponse = getForObject(url, String.class);

try {
List<MetabaseCollectionInfo> collections = objectMapper.readValue(jsonResponse, new TypeReference<List<MetabaseCollectionInfo>>() {});
return collections.stream()
.filter(coll -> coll.getName().equals(collectionName))
.findFirst()
.orElseThrow(() -> new RuntimeException("Collection with name " + collectionName + " not found."));
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve collection", e);
}
}

public void createQuestionForTable(Database database, TableDetails tableDetails, String addressTableName, String addressField, String tableField) throws Exception {
TableDetails addressTableDetails = getTableDetailsByDisplayName(database, addressTableName);
FieldDetails joinField1 = getFieldDetailsByName(database, addressTableName, addressField);
FieldDetails joinField2 = getFieldDetailsByName(database, tableDetails.getName(), tableField);

ArrayNode joinsArray = objectMapper.createArrayNode();
MetabaseQuery query = new MetabaseQueryBuilder(database, joinsArray)
.forTable(tableDetails)
.joinWith(addressTableDetails, joinField1, joinField2)
.build();

MetabaseRequestBody requestBody = new MetabaseRequestBody(
"Address + " + tableDetails.getDisplayName(),
query,
VisualizationType.TABLE,
null,
objectMapper.createObjectNode(),
getCollectionByName(database.getName()).getId(),
CardType.QUESTION
);

postForObject(metabaseApiUrl + "/card", requestBody.toJson(objectMapper), JsonNode.class);
}

public FieldDetails getFieldDetailsByName(Database database, String tableName, String fieldName) {
List<FieldDetails> fieldsList = getFields(database);
String snakeCaseTableName = S.toSnakeCase(tableName);

return fieldsList.stream()
.filter(field -> snakeCaseTableName.equals(field.getTableName()) && fieldName.equals(field.getName()))
.findFirst()
.orElseThrow(() -> new RuntimeException("Field " + fieldName + " not found in table " + tableName));
}

public MetabaseDatabaseInfo getDatabaseDetails(Database database) {
String url = metabaseApiUrl + "/database/" + database.getId() + "?include=tables";
String jsonResponse = getForObject(url, String.class);

try {
return objectMapper.readValue(jsonResponse, MetabaseDatabaseInfo.class);
} catch (Exception e) {
throw new RuntimeException("Failed to parse database details", e);
}
}

public List<FieldDetails> getFields(int databaseId) {
String url = metabaseApiUrl + "/database/" + databaseId + "/fields";
public List<FieldDetails> getFields(Database database) {
String url = metabaseApiUrl + "/database/" + database.getId() + "/fields";
String jsonResponse = getForObject(url, String.class);

try {
return objectMapper.readValue(jsonResponse, new TypeReference<List<FieldDetails>>() {});
} catch (Exception e) {
throw new RuntimeException("Failed to parse fields", e);
}
}

public TableDetails getTableDetailsByDisplayName(Database database, String tableName) {
MetabaseDatabaseInfo databaseInfo = getDatabaseDetails(database);
return databaseInfo.getTables().stream()
.filter(tableDetail -> tableDetail.nameMatches(tableName))
.findFirst()
.orElseThrow(() -> new RuntimeException("Table with name " + tableName + " not found."));
}

public DatabaseSyncStatus getInitialSyncStatus(int databaseId) {
String url = metabaseApiUrl + "/database/" + databaseId;
String jsonResponse = getForObject(url, String.class);
Expand All @@ -63,4 +138,13 @@ public DatasetResponse getDataset(String requestBody) {
throw new RuntimeException("Failed to parse dataset response", e);
}
}

public DatasetResponse findAll(TableDetails table, Database database) {
String requestBody = createRequestBodyForDataset(database, table);
return getDataset(requestBody);
}

private String createRequestBodyForDataset(Database database,TableDetails table) {
return "{\"database\":" + database.getId() + ",\"query\":{\"source-table\":" + table.getId() + "},\"type\":\"query\",\"parameters\":[]}";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.avni.server.domain.metabase;

public class MetabaseCollectionInfo {
private String name;
private int id;
private boolean isPersonal;

public MetabaseCollectionInfo(String name, int id, boolean isPersonal) {
this.name = name;
this.id = id;
this.isPersonal = isPersonal;
}

public String getName() {
return name;
}

public int getId() {
return id;
}

public boolean isPersonal() {
return isPersonal;
}

public void setName(String name) {
this.name = name;
}

public void setId(int id) {
this.id = id;
}

public void setPersonal(boolean personal) {
isPersonal = personal;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,24 @@
import com.fasterxml.jackson.databind.node.ObjectNode;

public class MetabaseQuery {
private final int databaseId;
private final int sourceTable;
private final Database database;
private final ArrayNode joins;
private final QueryType type = QueryType.QUERY;


public MetabaseQuery(int databaseId,int sourceTable, ArrayNode joins) {
this.databaseId = databaseId;
this.sourceTable = sourceTable;
public MetabaseQuery(Database database, ArrayNode joins) {
this.database = database;
this.joins = joins;
}

public int getDatabaseId() {
return databaseId;
return database.getId();
}


public ObjectNode toJson(ObjectMapper objectMapper) {
ObjectNode queryNode = objectMapper.createObjectNode();
queryNode.put("source-table", sourceTable);
queryNode.put("database", database.getId());
queryNode.set("joins", joins);
queryNode.put("type", type.toString());


queryNode.put("type", "query");
return queryNode;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// to be completed
package org.avni.server.domain.metabase;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class MetabaseQueryBuilder {
private final Database database;
private ArrayNode joins;

public MetabaseQueryBuilder(Database database, ArrayNode joins) {
this.database = database;
this.joins = joins;
}

public MetabaseQueryBuilder forTable(TableDetails tableDetails) {
// code to be added
return this;
}


public MetabaseQueryBuilder joinWith(TableDetails joinTable, FieldDetails originField, FieldDetails destinationField) {
// Build the join condition and add to the joins array
ObjectMapper objectMapper = new ObjectMapper();
ArrayNode joinCondition = objectMapper.createArrayNode();

joinCondition.add(ConditionType.EQUAL.getOperator());
joinCondition.add(objectMapper.createArrayNode().add("field").add(originField.getId()));
joinCondition.add(objectMapper.createArrayNode().add("field").add(destinationField.getId()));

joins.add(joinCondition);
return this;
}


public MetabaseQuery build() {
return new MetabaseQuery(database, joins);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,7 @@ public String getDisplayName() {
return displayName;
}

public boolean nameMatches(String tableName) {
return tableName.equals(getDisplayName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,46 +29,14 @@ public AddressQuestionCreationService(@Lazy DatabaseService databaseService, Dat

@Override
public void createQuestionForTable(String tableName, String addressTableName, String addressField, String tableField) throws Exception {
int addressTableId = databaseService.getTableIdByName(addressTableName);
int joinFieldId1 = databaseService.getFieldIdByTableNameAndFieldName(addressTableName, addressField);
int tableId = databaseService.getTableIdByName(tableName);
int joinFieldId2 = databaseService.getFieldIdByTableNameAndFieldName(tableName, tableField);
Database database = databaseService.getGlobalDatabase();
TableDetails tableDetails = databaseRepository.getTableDetailsByDisplayName(database, tableName);

MetabaseJoin join = new MetabaseJoin("all", tableName, tableId, joinFieldId1, joinFieldId2, tableName, objectMapper);

ArrayNode joinsArray = objectMapper.createArrayNode();
joinsArray.add(join.toJson(objectMapper));

MetabaseQuery query = new MetabaseQuery(databaseService.getDatabaseId(), addressTableId, joinsArray);

MetabaseRequestBody requestBody = new MetabaseRequestBody(
"Address + " + tableName, query, VisualizationType.TABLE, null, objectMapper.createObjectNode(), databaseService.getCollectionId(), CardType.QUESTION);

databaseRepository.postForObject(metabaseApiUrl + "/card", requestBody.toJson(objectMapper), JsonNode.class);
databaseRepository.createQuestionForTable(database, tableDetails, addressTableName, addressField, tableField);
}

@Override
public void createQuestionForTable(String tableName, String schema) {
int tableId = databaseService.getTableIdByName(tableName, schema);

ObjectNode datasetQuery = objectMapper.createObjectNode();
datasetQuery.put("database", databaseService.getDatabaseId());
datasetQuery.put("type", "query");

ObjectNode query = objectMapper.createObjectNode();
query.put("source-table", tableId);
datasetQuery.set("query", query);

ObjectNode body = objectMapper.createObjectNode();
body.put("name", tableName);
body.set("dataset_query", datasetQuery);
body.put("display", "table");
body.putNull("description");
body.set("visualization_settings", objectMapper.createObjectNode());
body.put("collection_id", databaseService.getCollectionId());
body.putNull("collection_position");
body.putNull("result_metadata");

databaseRepository.postForObject(metabaseApiUrl + "/card", body, JsonNode.class);
// to be added
}
}
Loading

0 comments on commit b2604a0

Please sign in to comment.