Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.openmetadata.service.jdbi3.CollectionDAO Maven / Gradle / Ivy
/*
* Copyright 2021 Collate
* Licensed 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.openmetadata.service.jdbi3;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.schema.type.Relationship.CONTAINS;
import static org.openmetadata.schema.type.Relationship.MENTIONED_IN;
import static org.openmetadata.service.Entity.GLOSSARY_TERM;
import static org.openmetadata.service.Entity.ORGANIZATION_NAME;
import static org.openmetadata.service.Entity.QUERY;
import static org.openmetadata.service.jdbi3.ListFilter.escapeApostrophe;
import static org.openmetadata.service.jdbi3.locator.ConnectionType.MYSQL;
import static org.openmetadata.service.jdbi3.locator.ConnectionType.POSTGRES;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.jdbi.v3.core.mapper.RowMapper;
import org.jdbi.v3.core.statement.StatementContext;
import org.jdbi.v3.core.statement.StatementException;
import org.jdbi.v3.sqlobject.CreateSqlObject;
import org.jdbi.v3.sqlobject.config.RegisterRowMapper;
import org.jdbi.v3.sqlobject.customizer.Bind;
import org.jdbi.v3.sqlobject.customizer.BindBeanList;
import org.jdbi.v3.sqlobject.customizer.BindList;
import org.jdbi.v3.sqlobject.customizer.BindMap;
import org.jdbi.v3.sqlobject.customizer.Define;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
import org.openmetadata.api.configuration.UiThemePreference;
import org.openmetadata.schema.TokenInterface;
import org.openmetadata.schema.analytics.ReportData;
import org.openmetadata.schema.analytics.WebAnalyticEvent;
import org.openmetadata.schema.api.configuration.LoginConfiguration;
import org.openmetadata.schema.api.configuration.profiler.ProfilerConfiguration;
import org.openmetadata.schema.auth.EmailVerificationToken;
import org.openmetadata.schema.auth.PasswordResetToken;
import org.openmetadata.schema.auth.PersonalAccessToken;
import org.openmetadata.schema.auth.RefreshToken;
import org.openmetadata.schema.auth.TokenType;
import org.openmetadata.schema.dataInsight.DataInsightChart;
import org.openmetadata.schema.dataInsight.custom.DataInsightCustomChart;
import org.openmetadata.schema.dataInsight.kpi.Kpi;
import org.openmetadata.schema.email.SmtpSettings;
import org.openmetadata.schema.entities.docStore.Document;
import org.openmetadata.schema.entity.Bot;
import org.openmetadata.schema.entity.Type;
import org.openmetadata.schema.entity.app.App;
import org.openmetadata.schema.entity.app.AppMarketPlaceDefinition;
import org.openmetadata.schema.entity.automations.Workflow;
import org.openmetadata.schema.entity.classification.Classification;
import org.openmetadata.schema.entity.classification.Tag;
import org.openmetadata.schema.entity.data.APICollection;
import org.openmetadata.schema.entity.data.APIEndpoint;
import org.openmetadata.schema.entity.data.Chart;
import org.openmetadata.schema.entity.data.Container;
import org.openmetadata.schema.entity.data.Dashboard;
import org.openmetadata.schema.entity.data.DashboardDataModel;
import org.openmetadata.schema.entity.data.Database;
import org.openmetadata.schema.entity.data.DatabaseSchema;
import org.openmetadata.schema.entity.data.Glossary;
import org.openmetadata.schema.entity.data.GlossaryTerm;
import org.openmetadata.schema.entity.data.Metrics;
import org.openmetadata.schema.entity.data.MlModel;
import org.openmetadata.schema.entity.data.Pipeline;
import org.openmetadata.schema.entity.data.Query;
import org.openmetadata.schema.entity.data.Report;
import org.openmetadata.schema.entity.data.SearchIndex;
import org.openmetadata.schema.entity.data.StoredProcedure;
import org.openmetadata.schema.entity.data.Table;
import org.openmetadata.schema.entity.data.Topic;
import org.openmetadata.schema.entity.domains.DataProduct;
import org.openmetadata.schema.entity.domains.Domain;
import org.openmetadata.schema.entity.events.EventSubscription;
import org.openmetadata.schema.entity.policies.Policy;
import org.openmetadata.schema.entity.services.APIService;
import org.openmetadata.schema.entity.services.DashboardService;
import org.openmetadata.schema.entity.services.DatabaseService;
import org.openmetadata.schema.entity.services.MessagingService;
import org.openmetadata.schema.entity.services.MetadataService;
import org.openmetadata.schema.entity.services.MlModelService;
import org.openmetadata.schema.entity.services.PipelineService;
import org.openmetadata.schema.entity.services.SearchService;
import org.openmetadata.schema.entity.services.StorageService;
import org.openmetadata.schema.entity.services.connections.TestConnectionDefinition;
import org.openmetadata.schema.entity.services.ingestionPipelines.IngestionPipeline;
import org.openmetadata.schema.entity.teams.Persona;
import org.openmetadata.schema.entity.teams.Role;
import org.openmetadata.schema.entity.teams.Team;
import org.openmetadata.schema.entity.teams.User;
import org.openmetadata.schema.settings.Settings;
import org.openmetadata.schema.settings.SettingsType;
import org.openmetadata.schema.tests.TestCase;
import org.openmetadata.schema.tests.TestDefinition;
import org.openmetadata.schema.tests.TestSuite;
import org.openmetadata.schema.type.EntityReference;
import org.openmetadata.schema.type.EventType;
import org.openmetadata.schema.type.Include;
import org.openmetadata.schema.type.Relationship;
import org.openmetadata.schema.type.TagLabel;
import org.openmetadata.schema.type.UsageDetails;
import org.openmetadata.schema.type.UsageStats;
import org.openmetadata.schema.util.EntitiesCount;
import org.openmetadata.schema.util.ServicesCount;
import org.openmetadata.schema.utils.EntityInterfaceUtil;
import org.openmetadata.service.Entity;
import org.openmetadata.service.jdbi3.CollectionDAO.TagUsageDAO.TagLabelMapper;
import org.openmetadata.service.jdbi3.CollectionDAO.UsageDAO.UsageDetailsMapper;
import org.openmetadata.service.jdbi3.FeedRepository.FilterType;
import org.openmetadata.service.jdbi3.locator.ConnectionAwareSqlQuery;
import org.openmetadata.service.jdbi3.locator.ConnectionAwareSqlUpdate;
import org.openmetadata.service.resources.feeds.MessageParser.EntityLink;
import org.openmetadata.service.resources.tags.TagLabelUtil;
import org.openmetadata.service.util.EntityUtil;
import org.openmetadata.service.util.FullyQualifiedName;
import org.openmetadata.service.util.JsonUtils;
import org.openmetadata.service.util.jdbi.BindFQN;
import org.openmetadata.service.util.jdbi.BindUUID;
public interface CollectionDAO {
@CreateSqlObject
DatabaseDAO databaseDAO();
@CreateSqlObject
DatabaseSchemaDAO databaseSchemaDAO();
@CreateSqlObject
EntityRelationshipDAO relationshipDAO();
@CreateSqlObject
FieldRelationshipDAO fieldRelationshipDAO();
@CreateSqlObject
EntityExtensionDAO entityExtensionDAO();
@CreateSqlObject
AppExtensionTimeSeries appExtensionTimeSeriesDao();
@CreateSqlObject
EntityExtensionTimeSeriesDAO entityExtensionTimeSeriesDao();
@CreateSqlObject
ReportDataTimeSeriesDAO reportDataTimeSeriesDao();
@CreateSqlObject
ProfilerDataTimeSeriesDAO profilerDataTimeSeriesDao();
@CreateSqlObject
DataQualityDataTimeSeriesDAO dataQualityDataTimeSeriesDao();
@CreateSqlObject
TestCaseResolutionStatusTimeSeriesDAO testCaseResolutionStatusTimeSeriesDao();
@CreateSqlObject
RoleDAO roleDAO();
@CreateSqlObject
UserDAO userDAO();
@CreateSqlObject
TeamDAO teamDAO();
@CreateSqlObject
PersonaDAO personaDAO();
@CreateSqlObject
TagUsageDAO tagUsageDAO();
@CreateSqlObject
TagDAO tagDAO();
@CreateSqlObject
ClassificationDAO classificationDAO();
@CreateSqlObject
TableDAO tableDAO();
@CreateSqlObject
QueryDAO queryDAO();
@CreateSqlObject
UsageDAO usageDAO();
@CreateSqlObject
MetricsDAO metricsDAO();
@CreateSqlObject
ChartDAO chartDAO();
@CreateSqlObject
ApplicationDAO applicationDAO();
@CreateSqlObject
ApplicationMarketPlaceDAO applicationMarketPlaceDAO();
@CreateSqlObject
PipelineDAO pipelineDAO();
@CreateSqlObject
DashboardDAO dashboardDAO();
@CreateSqlObject
ReportDAO reportDAO();
@CreateSqlObject
TopicDAO topicDAO();
@CreateSqlObject
MlModelDAO mlModelDAO();
@CreateSqlObject
SearchIndexDAO searchIndexDAO();
@CreateSqlObject
GlossaryDAO glossaryDAO();
@CreateSqlObject
GlossaryTermDAO glossaryTermDAO();
@CreateSqlObject
BotDAO botDAO();
@CreateSqlObject
DomainDAO domainDAO();
@CreateSqlObject
DataProductDAO dataProductDAO();
@CreateSqlObject
EventSubscriptionDAO eventSubscriptionDAO();
@CreateSqlObject
PolicyDAO policyDAO();
@CreateSqlObject
IngestionPipelineDAO ingestionPipelineDAO();
@CreateSqlObject
DatabaseServiceDAO dbServiceDAO();
@CreateSqlObject
MetadataServiceDAO metadataServiceDAO();
@CreateSqlObject
PipelineServiceDAO pipelineServiceDAO();
@CreateSqlObject
MlModelServiceDAO mlModelServiceDAO();
@CreateSqlObject
DashboardServiceDAO dashboardServiceDAO();
@CreateSqlObject
MessagingServiceDAO messagingServiceDAO();
@CreateSqlObject
StorageServiceDAO storageServiceDAO();
@CreateSqlObject
SearchServiceDAO searchServiceDAO();
@CreateSqlObject
APIServiceDAO apiServiceDAO();
@CreateSqlObject
ContainerDAO containerDAO();
@CreateSqlObject
FeedDAO feedDAO();
@CreateSqlObject
StoredProcedureDAO storedProcedureDAO();
@CreateSqlObject
ChangeEventDAO changeEventDAO();
@CreateSqlObject
TypeEntityDAO typeEntityDAO();
@CreateSqlObject
TestDefinitionDAO testDefinitionDAO();
@CreateSqlObject
TestConnectionDefinitionDAO testConnectionDefinitionDAO();
@CreateSqlObject
TestSuiteDAO testSuiteDAO();
@CreateSqlObject
TestCaseDAO testCaseDAO();
@CreateSqlObject
WebAnalyticEventDAO webAnalyticEventDAO();
@CreateSqlObject
DataInsightCustomChartDAO dataInsightCustomChartDAO();
@CreateSqlObject
DataInsightChartDAO dataInsightChartDAO();
@CreateSqlObject
SystemDAO systemDAO();
@CreateSqlObject
TokenDAO getTokenDAO();
@CreateSqlObject
KpiDAO kpiDAO();
@CreateSqlObject
WorkflowDAO workflowDAO();
@CreateSqlObject
DataModelDAO dashboardDataModelDAO();
@CreateSqlObject
DocStoreDAO docStoreDAO();
@CreateSqlObject
SuggestionDAO suggestionDAO();
@CreateSqlObject
APICollectionDAO apiCollectionDAO();
@CreateSqlObject
APIEndpointDAO apiEndpointDAO();
interface DashboardDAO extends EntityDAO {
@Override
default String getTableName() {
return "dashboard_entity";
}
@Override
default Class getEntityClass() {
return Dashboard.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
}
interface DashboardServiceDAO extends EntityDAO {
@Override
default String getTableName() {
return "dashboard_service_entity";
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
@Override
default Class getEntityClass() {
return DashboardService.class;
}
}
interface DatabaseDAO extends EntityDAO {
@Override
default String getTableName() {
return "database_entity";
}
@Override
default Class getEntityClass() {
return Database.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
}
interface DatabaseSchemaDAO extends EntityDAO {
@Override
default String getTableName() {
return "database_schema_entity";
}
@Override
default Class getEntityClass() {
return DatabaseSchema.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
}
interface DatabaseServiceDAO extends EntityDAO {
@Override
default String getTableName() {
return "dbservice_entity";
}
@Override
default Class getEntityClass() {
return DatabaseService.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface MetadataServiceDAO extends EntityDAO {
@Override
default String getTableName() {
return "metadata_service_entity";
}
@Override
default Class getEntityClass() {
return MetadataService.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface TestConnectionDefinitionDAO extends EntityDAO {
@Override
default String getTableName() {
return "test_connection_definition";
}
@Override
default Class getEntityClass() {
return TestConnectionDefinition.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface StorageServiceDAO extends EntityDAO {
@Override
default String getTableName() {
return "storage_service_entity";
}
@Override
default Class getEntityClass() {
return StorageService.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface ContainerDAO extends EntityDAO {
@Override
default String getTableName() {
return "storage_container_entity";
}
@Override
default Class getEntityClass() {
return Container.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
@Override
default List listBefore(
ListFilter filter, int limit, String beforeName, String beforeId) {
boolean root = Boolean.parseBoolean(filter.getQueryParam("root"));
String condition = filter.getCondition();
// By default, root will be false. We won't filter the results then
if (!root) {
return EntityDAO.super.listBefore(filter, limit, beforeName, beforeId);
}
String sqlCondition = String.format("%s AND er.toId is NULL", condition);
return listBefore(
getTableName(), filter.getQueryParams(), sqlCondition, limit, beforeName, beforeId);
}
@Override
default List listAfter(ListFilter filter, int limit, String afterName, String afterId) {
boolean root = Boolean.parseBoolean(filter.getQueryParam("root"));
String condition = filter.getCondition();
if (!root) {
return EntityDAO.super.listAfter(filter, limit, afterName, afterId);
}
String sqlCondition = String.format("%s AND er.toId is NULL", condition);
return listAfter(
getTableName(), filter.getQueryParams(), sqlCondition, limit, afterName, afterId);
}
@Override
default int listCount(ListFilter filter) {
boolean root = Boolean.parseBoolean(filter.getQueryParam("root"));
String condition = filter.getCondition();
if (!root) {
return EntityDAO.super.listCount(filter);
}
String sqlCondition = String.format("%s AND er.toId is NULL", condition);
return listCount(getTableName(), getNameHashColumn(), filter.getQueryParams(), sqlCondition);
}
@SqlQuery(
value =
"SELECT json FROM ("
+ "SELECT name,id, ce.json FROM ce "
+ "LEFT JOIN ("
+ " SELECT toId FROM entity_relationship "
+ " WHERE fromEntity = 'container' AND toEntity = 'container' AND relation = 0 "
+ ") er "
+ "on ce.id = er.toId "
+ " AND "
+ "(name < :beforeName OR (name = :beforeName AND id < :beforeId)) "
+ "ORDER BY name DESC,id DESC "
+ "LIMIT :limit"
+ ") last_rows_subquery ORDER BY name,id")
List listBefore(
@Define("table") String table,
@BindMap Map params,
@Define("sqlCondition") String sqlCondition,
@Bind("limit") int limit,
@Bind("beforeName") String beforeName,
@Bind("beforeId") String beforeId);
@SqlQuery(
value =
"SELECT ce.json FROM ce "
+ "LEFT JOIN ("
+ " SELECT toId FROM entity_relationship "
+ " WHERE fromEntity = 'container' AND toEntity = 'container' AND relation = 0 "
+ ") er "
+ "on ce.id = er.toId "
+ " AND "
+ "(name > :afterName OR (name = :afterName AND id > :afterId)) "
+ "ORDER BY name,id "
+ "LIMIT :limit")
List listAfter(
@Define("table") String table,
@BindMap Map params,
@Define("sqlCondition") String sqlCondition,
@Bind("limit") int limit,
@Bind("afterName") String afterName,
@Bind("afterId") String afterId);
@ConnectionAwareSqlQuery(
value =
"SELECT count() FROM ce "
+ "LEFT JOIN ("
+ " SELECT toId FROM entity_relationship "
+ " WHERE fromEntity = 'container' AND toEntity = 'container' AND relation = 0 "
+ ") er "
+ "on ce.id = er.toId "
+ "",
connectionType = MYSQL)
@ConnectionAwareSqlQuery(
value =
"SELECT count(*) FROM ce "
+ "LEFT JOIN ("
+ " SELECT toId FROM entity_relationship "
+ " WHERE fromEntity = 'container' AND toEntity = 'container' AND relation = 0 "
+ ") er "
+ "on ce.id = er.toId "
+ "",
connectionType = POSTGRES)
int listCount(
@Define("table") String table,
@Define("nameHashColumn") String nameHashColumn,
@BindMap Map params,
@Define("sqlCondition") String mysqlCond);
}
interface SearchServiceDAO extends EntityDAO {
@Override
default String getTableName() {
return "search_service_entity";
}
@Override
default Class getEntityClass() {
return SearchService.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface APIServiceDAO extends EntityDAO {
@Override
default String getTableName() {
return "api_service_entity";
}
@Override
default Class getEntityClass() {
return APIService.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface SearchIndexDAO extends EntityDAO {
@Override
default String getTableName() {
return "search_index_entity";
}
@Override
default Class getEntityClass() {
return SearchIndex.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
}
interface EntityExtensionDAO {
@ConnectionAwareSqlUpdate(
value =
"REPLACE INTO entity_extension(id, extension, jsonSchema, json) "
+ "VALUES (:id, :extension, :jsonSchema, :json)",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO entity_extension(id, extension, jsonSchema, json) "
+ "VALUES (:id, :extension, :jsonSchema, (:json :: jsonb)) "
+ "ON CONFLICT (id, extension) DO UPDATE SET jsonSchema = EXCLUDED.jsonSchema, json = EXCLUDED.json",
connectionType = POSTGRES)
void insert(
@BindUUID("id") UUID id,
@Bind("extension") String extension,
@Bind("jsonSchema") String jsonSchema,
@Bind("json") String json);
@ConnectionAwareSqlUpdate(
value = "UPDATE entity_extension SET json = :json where (json -> '$.id') = :id",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value = "UPDATE entity_extension SET json = (:json :: jsonb) where (json ->> 'id) = :id",
connectionType = POSTGRES)
void update(@BindUUID("id") UUID id, @Bind("json") String json);
@SqlQuery("SELECT json FROM entity_extension WHERE id = :id AND extension = :extension")
String getExtension(@BindUUID("id") UUID id, @Bind("extension") String extension);
@RegisterRowMapper(ExtensionMapper.class)
@SqlQuery(
"SELECT extension, json FROM entity_extension WHERE id = :id AND extension "
+ "LIKE CONCAT (:extensionPrefix, '.%') "
+ "ORDER BY extension")
List getExtensions(
@BindUUID("id") UUID id, @Bind("extensionPrefix") String extensionPrefix);
@RegisterRowMapper(ExtensionMapper.class)
@SqlQuery(
"SELECT extension, json FROM entity_extension WHERE id = :id AND extension "
+ "LIKE CONCAT (:extensionPrefix, '.%') "
+ "ORDER BY extension DESC "
+ "LIMIT :limit OFFSET :offset")
List getExtensionsWithOffset(
@BindUUID("id") UUID id,
@Bind("extensionPrefix") String extensionPrefix,
@Bind("limit") int limit,
@Bind("offset") int offset);
@SqlUpdate("DELETE FROM entity_extension WHERE id = :id AND extension = :extension")
void delete(@BindUUID("id") UUID id, @Bind("extension") String extension);
@SqlUpdate("DELETE FROM entity_extension WHERE extension = :extension")
void deleteExtension(@Bind("extension") String extension);
@SqlUpdate("DELETE FROM entity_extension WHERE id = :id")
void deleteAll(@BindUUID("id") UUID id);
}
class EntityVersionPair {
@Getter private final Double version;
@Getter private final String entityJson;
public EntityVersionPair(ExtensionRecord extensionRecord) {
this.version = EntityUtil.getVersion(extensionRecord.extensionName());
this.entityJson = extensionRecord.extensionJson();
}
}
record ExtensionRecord(String extensionName, String extensionJson) {}
class ExtensionMapper implements RowMapper {
@Override
public ExtensionRecord map(ResultSet rs, StatementContext ctx) throws SQLException {
return new ExtensionRecord(rs.getString("extension"), rs.getString("json"));
}
}
@Getter
@Builder
class EntityRelationshipRecord {
private UUID id;
private String type;
private String json;
}
@Getter
@Builder
class EntityRelationshipObject {
private String fromId;
private String toId;
private String fromEntity;
private String toEntity;
private int relation;
}
@Getter
@Builder
class ReportDataRow {
private String rowNum;
private ReportData reportData;
}
@Getter
@Builder
class QueryList {
private String fqn;
private Query query;
}
interface EntityRelationshipDAO {
default void insert(UUID fromId, UUID toId, String fromEntity, String toEntity, int relation) {
insert(fromId, toId, fromEntity, toEntity, relation, null);
}
default void bulkInsertToRelationship(
UUID fromId, List toIds, String fromEntity, String toEntity, int relation) {
List insertToRelationship =
toIds.stream()
.map(
testCase ->
EntityRelationshipObject.builder()
.fromId(fromId.toString())
.toId(testCase.toString())
.fromEntity(fromEntity)
.toEntity(toEntity)
.relation(relation)
.build())
.collect(Collectors.toList());
bulkInsertTo(insertToRelationship);
}
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO entity_relationship(fromId, toId, fromEntity, toEntity, relation, json) "
+ "VALUES (:fromId, :toId, :fromEntity, :toEntity, :relation, :json) "
+ "ON DUPLICATE KEY UPDATE json = :json",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO entity_relationship(fromId, toId, fromEntity, toEntity, relation, json) VALUES "
+ "(:fromId, :toId, :fromEntity, :toEntity, :relation, (:json :: jsonb)) "
+ "ON CONFLICT (fromId, toId, relation) DO UPDATE SET json = EXCLUDED.json",
connectionType = POSTGRES)
void insert(
@BindUUID("fromId") UUID fromId,
@BindUUID("toId") UUID toId,
@Bind("fromEntity") String fromEntity,
@Bind("toEntity") String toEntity,
@Bind("relation") int relation,
@Bind("json") String json);
@ConnectionAwareSqlUpdate(
value =
"INSERT IGNORE INTO entity_relationship(fromId, toId, fromEntity, toEntity, relation) VALUES ",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO entity_relationship(fromId, toId, fromEntity, toEntity, relation) VALUES "
+ "ON CONFLICT DO NOTHING",
connectionType = POSTGRES)
void bulkInsertTo(
@BindBeanList(
value = "values",
propertyNames = {"fromId", "toId", "fromEntity", "toEntity", "relation"})
List values);
//
// Find to operations
//
@SqlQuery(
"SELECT toId, toEntity, json FROM entity_relationship "
+ "WHERE fromId = :fromId AND fromEntity = :fromEntity AND relation IN ()")
@RegisterRowMapper(ToRelationshipMapper.class)
List findTo(
@BindUUID("fromId") UUID fromId,
@Bind("fromEntity") String fromEntity,
@BindList("relation") List relation);
default List findTo(UUID fromId, String fromEntity, int relation) {
return findTo(fromId, fromEntity, List.of(relation));
}
@SqlQuery(
"SELECT toId, toEntity, json FROM entity_relationship "
+ "WHERE fromId = :fromId AND fromEntity = :fromEntity AND relation = :relation AND toEntity = :toEntity")
@RegisterRowMapper(ToRelationshipMapper.class)
List findTo(
@BindUUID("fromId") UUID fromId,
@Bind("fromEntity") String fromEntity,
@Bind("relation") int relation,
@Bind("toEntity") String toEntity);
@ConnectionAwareSqlQuery(
value =
"SELECT toId, toEntity, json FROM entity_relationship "
+ "WHERE JSON_UNQUOTE(JSON_EXTRACT(json, '$.pipeline.id')) =:fromId OR fromId = :fromId AND relation = :relation "
+ "ORDER BY toId",
connectionType = MYSQL)
@ConnectionAwareSqlQuery(
value =
"SELECT toId, toEntity, json FROM entity_relationship "
+ "WHERE json->'pipeline'->>'id' =:fromId OR fromId = :fromId AND relation = :relation "
+ "ORDER BY toId",
connectionType = POSTGRES)
@RegisterRowMapper(ToRelationshipMapper.class)
List findToPipeline(
@BindUUID("fromId") UUID fromId, @Bind("relation") int relation);
//
// Find from operations
//
@SqlQuery(
"SELECT fromId, fromEntity, json FROM entity_relationship "
+ "WHERE toId = :toId AND toEntity = :toEntity AND relation = :relation AND fromEntity = :fromEntity ")
@RegisterRowMapper(FromRelationshipMapper.class)
List findFrom(
@BindUUID("toId") UUID toId,
@Bind("toEntity") String toEntity,
@Bind("relation") int relation,
@Bind("fromEntity") String fromEntity);
@SqlQuery(
"SELECT fromId, fromEntity, json FROM entity_relationship "
+ "WHERE toId = :toId AND toEntity = :toEntity AND relation = :relation")
@RegisterRowMapper(FromRelationshipMapper.class)
List findFrom(
@BindUUID("toId") UUID toId,
@Bind("toEntity") String toEntity,
@Bind("relation") int relation);
@ConnectionAwareSqlQuery(
value =
"SELECT fromId, fromEntity, json FROM entity_relationship "
+ "WHERE JSON_UNQUOTE(JSON_EXTRACT(json, '$.pipeline.id')) = :toId OR toId = :toId AND relation = :relation "
+ "ORDER BY fromId",
connectionType = MYSQL)
@ConnectionAwareSqlQuery(
value =
"SELECT fromId, fromEntity, json FROM entity_relationship "
+ "WHERE json->'pipeline'->>'id' = :toId OR toId = :toId AND relation = :relation "
+ "ORDER BY fromId",
connectionType = POSTGRES)
@RegisterRowMapper(FromRelationshipMapper.class)
List findFromPipeline(
@BindUUID("toId") UUID toId, @Bind("relation") int relation);
@ConnectionAwareSqlQuery(
value =
"SELECT toId, toEntity, fromId, fromEntity, relation FROM entity_relationship "
+ "WHERE JSON_UNQUOTE(JSON_EXTRACT(json, '$.source')) = :source AND (toId = :toId AND toEntity = :toEntity) "
+ "AND relation = :relation ORDER BY fromId",
connectionType = MYSQL)
@ConnectionAwareSqlQuery(
value =
"SELECT toId, toEntity, fromId, fromEntity, relation FROM entity_relationship "
+ "WHERE json->>'source' = :source AND (toId = :toId AND toEntity = :toEntity) "
+ "AND relation = :relation ORDER BY fromId",
connectionType = POSTGRES)
@RegisterRowMapper(RelationshipObjectMapper.class)
List findLineageBySource(
@BindUUID("toId") UUID toId,
@Bind("toEntity") String toEntity,
@Bind("source") String source,
@Bind("relation") int relation);
@ConnectionAwareSqlQuery(
value =
"SELECT toId, toEntity, fromId, fromEntity, relation FROM entity_relationship "
+ "WHERE JSON_UNQUOTE(JSON_EXTRACT(json, '$.pipeline.id')) =:toId OR toId = :toId AND relation = :relation "
+ "AND JSON_UNQUOTE(JSON_EXTRACT(json, '$.source')) = :source ORDER BY toId",
connectionType = MYSQL)
@ConnectionAwareSqlQuery(
value =
"SELECT toId, toEntity, fromId, fromEntity, relation FROM entity_relationship "
+ "WHERE json->'pipeline'->>'id' =:toId OR toId = :toId AND relation = :relation "
+ "AND json->>'source' = :source ORDER BY toId",
connectionType = POSTGRES)
@RegisterRowMapper(RelationshipObjectMapper.class)
List findLineageBySourcePipeline(
@BindUUID("toId") UUID toId,
@Bind("toEntity") String toEntity,
@Bind("source") String source,
@Bind("relation") int relation);
@SqlQuery(
"SELECT count(*) FROM entity_relationship WHERE fromEntity = :fromEntity AND toEntity = :toEntity")
int findIfAnyRelationExist(
@Bind("fromEntity") String fromEntity, @Bind("toEntity") String toEntity);
@SqlQuery(
"SELECT json FROM entity_relationship WHERE fromId = :fromId "
+ " AND toId = :toId "
+ " AND relation = :relation ")
String getRelation(
@BindUUID("fromId") UUID fromId,
@BindUUID("toId") UUID toId,
@Bind("relation") int relation);
//
// Delete Operations
//
@SqlUpdate(
"DELETE from entity_relationship WHERE fromId = :fromId "
+ "AND fromEntity = :fromEntity AND toId = :toId AND toEntity = :toEntity "
+ "AND relation = :relation")
int delete(
@BindUUID("fromId") UUID fromId,
@Bind("fromEntity") String fromEntity,
@BindUUID("toId") UUID toId,
@Bind("toEntity") String toEntity,
@Bind("relation") int relation);
// Delete all the entity relationship fromID --- relation --> entity of type toEntity
@SqlUpdate(
"DELETE from entity_relationship WHERE fromId = :fromId AND fromEntity = :fromEntity "
+ "AND relation = :relation AND toEntity = :toEntity")
void deleteFrom(
@BindUUID("fromId") UUID fromId,
@Bind("fromEntity") String fromEntity,
@Bind("relation") int relation,
@Bind("toEntity") String toEntity);
// Delete all the entity relationship toId <-- relation -- entity of type fromEntity
@SqlUpdate(
"DELETE from entity_relationship WHERE toId = :toId AND toEntity = :toEntity AND relation = :relation "
+ "AND fromEntity = :fromEntity")
void deleteTo(
@BindUUID("toId") UUID toId,
@Bind("toEntity") String toEntity,
@Bind("relation") int relation,
@Bind("fromEntity") String fromEntity);
@SqlUpdate(
"DELETE from entity_relationship WHERE toId = :toId AND toEntity = :toEntity AND relation = :relation")
void deleteTo(
@BindUUID("toId") UUID toId,
@Bind("toEntity") String toEntity,
@Bind("relation") int relation);
@SqlUpdate(
"DELETE from entity_relationship WHERE (toId = :id AND toEntity = :entity) OR "
+ "(fromId = :id AND fromEntity = :entity)")
void deleteAll(@BindUUID("id") UUID id, @Bind("entity") String entity);
@SqlUpdate("DELETE from entity_relationship WHERE fromId = :id or toId = :id")
void deleteAllWithId(@BindUUID("id") UUID id);
@ConnectionAwareSqlUpdate(
value =
"DELETE FROM entity_relationship "
+ "WHERE JSON_UNQUOTE(JSON_EXTRACT(json, '$.source')) = :source AND toId = :toId AND toEntity = :toEntity "
+ "AND relation = :relation",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"DELETE FROM entity_relationship "
+ "WHERE json->>'source' = :source AND (toId = :toId AND toEntity = :toEntity) "
+ "AND relation = :relation",
connectionType = POSTGRES)
void deleteLineageBySource(
@BindUUID("toId") UUID toId,
@Bind("toEntity") String toEntity,
@Bind("source") String source,
@Bind("relation") int relation);
@ConnectionAwareSqlUpdate(
value =
"DELETE FROM entity_relationship "
+ "WHERE JSON_UNQUOTE(JSON_EXTRACT(json, '$.pipeline.id')) =:toId OR toId = :toId AND relation = :relation "
+ "AND JSON_UNQUOTE(JSON_EXTRACT(json, '$.source')) = :source ORDER BY toId",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"DELETE FROM entity_relationship "
+ "WHERE json->'pipeline'->>'id' =:toId OR toId = :toId AND relation = :relation "
+ "AND json->>'source' = :source ORDER BY toId",
connectionType = POSTGRES)
void deleteLineageBySourcePipeline(
@BindUUID("toId") UUID toId,
@Bind("toEntity") String toEntity,
@Bind("source") String source,
@Bind("relation") int relation);
class FromRelationshipMapper implements RowMapper {
@Override
public EntityRelationshipRecord map(ResultSet rs, StatementContext ctx) throws SQLException {
return EntityRelationshipRecord.builder()
.id(UUID.fromString(rs.getString("fromId")))
.type(rs.getString("fromEntity"))
.json(rs.getString("json"))
.build();
}
}
class ToRelationshipMapper implements RowMapper {
@Override
public EntityRelationshipRecord map(ResultSet rs, StatementContext ctx) throws SQLException {
return EntityRelationshipRecord.builder()
.id(UUID.fromString(rs.getString("toId")))
.type(rs.getString("toEntity"))
.json(rs.getString("json"))
.build();
}
}
class RelationshipObjectMapper implements RowMapper {
@Override
public EntityRelationshipObject map(ResultSet rs, StatementContext ctx) throws SQLException {
return EntityRelationshipObject.builder()
.fromId(rs.getString("fromId"))
.fromEntity(rs.getString("fromEntity"))
.toEntity(rs.getString("toEntity"))
.toId(rs.getString("toId"))
.relation(rs.getInt("relation"))
.build();
}
}
}
interface FeedDAO {
@ConnectionAwareSqlUpdate(
value = "INSERT INTO thread_entity(json) VALUES (:json)",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value = "INSERT INTO thread_entity(json) VALUES (:json :: jsonb)",
connectionType = POSTGRES)
void insert(@Bind("json") String json);
@SqlQuery("SELECT json FROM thread_entity WHERE id = :id")
String findById(@BindUUID("id") UUID id);
@SqlQuery("SELECT json FROM thread_entity ORDER BY createdAt DESC")
List list();
@SqlQuery("SELECT count(id) FROM thread_entity ")
int listCount(@Define("condition") String condition);
@SqlUpdate("DELETE FROM thread_entity WHERE id = :id")
void delete(@BindUUID("id") UUID id);
@ConnectionAwareSqlUpdate(
value = "UPDATE task_sequence SET id=LAST_INSERT_ID(id+1)",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value = "UPDATE task_sequence SET id=(id+1) RETURNING id",
connectionType = POSTGRES)
void updateTaskId();
@SqlQuery("SELECT id FROM task_sequence LIMIT 1")
int getTaskId();
@SqlQuery("SELECT json FROM thread_entity WHERE taskId = :id")
String findByTaskId(@Bind("id") int id);
@SqlQuery("SELECT json FROM thread_entity ORDER BY createdAt DESC LIMIT :limit")
List list(@Bind("limit") int limit, @Define("condition") String condition);
@SqlQuery(
"SELECT json FROM thread_entity "
+ "WHERE type='Announcement' AND (:threadId IS NULL OR id != :threadId) "
+ "AND entityId = :entityId "
+ "AND (( :startTs >= announcementStart AND :startTs < announcementEnd) "
+ "OR (:endTs > announcementStart AND :endTs < announcementEnd) "
+ "OR (:startTs <= announcementStart AND :endTs >= announcementEnd))")
List listAnnouncementBetween(
@BindUUID("threadId") UUID threadId,
@BindUUID("entityId") UUID entityId,
@Bind("startTs") long startTs,
@Bind("endTs") long endTs);
@ConnectionAwareSqlQuery(
value =
"SELECT json FROM thread_entity AND "
+ "to_tsvector('simple', taskAssigneesIds) @@ to_tsquery('simple', :userTeamJsonPostgres) "
+ "ORDER BY createdAt DESC "
+ "LIMIT :limit",
connectionType = POSTGRES)
@ConnectionAwareSqlQuery(
value =
"SELECT json FROM thread_entity AND "
+ "MATCH(taskAssigneesIds) AGAINST (:userTeamJsonMysql IN BOOLEAN MODE) "
+ "ORDER BY createdAt DESC "
+ "LIMIT :limit",
connectionType = MYSQL)
List listTasksAssigned(
@Bind("userTeamJsonPostgres") String userTeamJsonPostgres,
@Bind("userTeamJsonMysql") String userTeamJsonMysql,
@Bind("limit") int limit,
@Define("condition") String condition);
@ConnectionAwareSqlQuery(
value =
"SELECT count(id) FROM thread_entity AND "
+ "to_tsvector('simple', taskAssigneesIds) @@ to_tsquery('simple', :userTeamJsonPostgres) ",
connectionType = POSTGRES)
@ConnectionAwareSqlQuery(
value =
"SELECT count(id) FROM thread_entity AND "
+ "MATCH(taskAssigneesIds) AGAINST (:userTeamJsonMysql IN BOOLEAN MODE) ",
connectionType = MYSQL)
int listCountTasksAssignedTo(
@Bind("userTeamJsonPostgres") String userTeamJsonPostgres,
@Bind("userTeamJsonMysql") String userTeamJsonMysql,
@Define("condition") String condition);
@ConnectionAwareSqlQuery(
value =
"SELECT json FROM thread_entity "
+ "AND (to_tsvector('simple', taskAssigneesIds) @@ to_tsquery('simple', :userTeamJsonPostgres) OR createdBy = :username) "
+ "ORDER BY createdAt DESC "
+ "LIMIT :limit",
connectionType = POSTGRES)
@ConnectionAwareSqlQuery(
value =
"SELECT json FROM thread_entity "
+ "AND (MATCH(taskAssigneesIds) AGAINST (:userTeamJsonMysql IN BOOLEAN MODE) OR createdBy = :username) "
+ "ORDER BY createdAt DESC "
+ "LIMIT :limit",
connectionType = MYSQL)
List listTasksOfUser(
@Bind("userTeamJsonPostgres") String userTeamJsonPostgres,
@Bind("userTeamJsonMysql") String userTeamJsonMysql,
@Bind("username") String username,
@Bind("limit") int limit,
@Define("condition") String condition);
@ConnectionAwareSqlQuery(
value =
"SELECT count(id) FROM thread_entity "
+ "AND (to_tsvector('simple', taskAssigneesIds) @@ to_tsquery('simple', :userTeamJsonPostgres) OR createdBy = :username) ",
connectionType = POSTGRES)
@ConnectionAwareSqlQuery(
value =
"SELECT count(id) FROM thread_entity "
+ "AND (MATCH(taskAssigneesIds) AGAINST (:userTeamJsonMysql IN BOOLEAN MODE) OR createdBy = :username) ",
connectionType = MYSQL)
int listCountTasksOfUser(
@Bind("userTeamJsonPostgres") String userTeamJsonPostgres,
@Bind("userTeamJsonMysql") String userTeamJsonMysql,
@Bind("username") String username,
@Define("condition") String condition);
@SqlQuery(
"SELECT json FROM thread_entity AND createdBy = :username ORDER BY createdAt DESC LIMIT :limit")
List listTasksAssigned(
@Bind("username") String username,
@Bind("limit") int limit,
@Define("condition") String condition);
@SqlQuery("SELECT count(id) FROM thread_entity AND createdBy = :username")
int listCountTasksAssignedBy(
@Bind("username") String username, @Define("condition") String condition);
@SqlQuery(
"SELECT json FROM thread_entity AND "
// Entity for which the thread is about is owned by the user or his teams
+ "(entityId in (SELECT toId FROM entity_relationship WHERE "
+ "((fromEntity='user' AND fromId= :userId) OR "
+ "(fromEntity='team' AND fromId IN ())) AND relation=8) OR "
+ "id in (SELECT toId FROM entity_relationship WHERE (fromEntity='user' AND fromId= :userId AND toEntity='THREAD' AND relation IN (1,2)))) "
+ "ORDER BY createdAt DESC "
+ "LIMIT :limit")
List listThreadsByOwner(
@BindUUID("userId") UUID userId,
@BindList("teamIds") List teamIds,
@Bind("limit") int limit,
@Define("condition") String condition);
@SqlQuery(
"SELECT count(id) FROM thread_entity AND "
+ "(entityId in (SELECT toId FROM entity_relationship WHERE "
+ "((fromEntity='user' AND fromId= :userId) OR "
+ "(fromEntity='team' AND fromId IN ())) AND relation=8) OR "
+ "id in (SELECT toId FROM entity_relationship WHERE (fromEntity='user' AND fromId= :userId AND toEntity='THREAD' AND relation IN (1,2)))) ")
int listCountThreadsByOwner(
@BindUUID("userId") UUID userId,
@BindList("teamIds") List teamIds,
@Define("condition") String condition);
@SqlQuery(
value =
"SELECT json "
+ " FROM thread_entity "
+ " WHERE testCaseResolutionStatusId = :testCaseResolutionStatusId")
String fetchThreadByTestCaseResolutionStatusId(
@BindUUID("testCaseResolutionStatusId") UUID testCaseResolutionStatusId);
default List listThreadsByEntityLink(
FeedFilter filter,
EntityLink entityLink,
int limit,
int relation,
String userName,
List teamNames) {
int filterRelation = -1;
if (userName != null && filter.getFilterType() == FilterType.MENTIONS) {
filterRelation = MENTIONED_IN.ordinal();
}
return listThreadsByEntityLink(
entityLink.getFullyQualifiedFieldValue(),
entityLink.getFullyQualifiedFieldType(),
limit,
relation,
userName,
teamNames,
filterRelation,
filter.getCondition());
}
@SqlQuery(
"SELECT json FROM thread_entity "
+ "AND hash_id in (SELECT fromFQNHash FROM field_relationship WHERE "
+ "(:fqnPrefixHash IS NULL OR toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR toFQNHash=:fqnPrefixHash) AND fromType='THREAD' AND "
+ "(:toType IS NULL OR toType LIKE CONCAT(:toType, '.%') OR toType=:toType) AND relation= :relation) "
+ "AND (:userName IS NULL OR MD5(id) in (SELECT toFQNHash FROM field_relationship WHERE "
+ " ((fromType='user' AND fromFQNHash= :userName) OR"
+ " (fromType='team' AND fromFQNHash IN ())) AND toType='THREAD' AND relation= :filterRelation) )"
+ "ORDER BY createdAt DESC "
+ "LIMIT :limit")
List listThreadsByEntityLink(
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
@Bind("toType") String toType,
@Bind("limit") int limit,
@Bind("relation") int relation,
@BindFQN("userName") String userName,
@BindList("teamNames") List teamNames,
@Bind("filterRelation") int filterRelation,
@Define("condition") String condition);
default int listCountThreadsByEntityLink(
FeedFilter filter,
EntityLink entityLink,
int relation,
String userName,
List teamNames) {
int filterRelation = -1;
if (userName != null && filter.getFilterType() == FilterType.MENTIONS) {
filterRelation = MENTIONED_IN.ordinal();
}
return listCountThreadsByEntityLink(
entityLink.getFullyQualifiedFieldValue(),
entityLink.getFullyQualifiedFieldType(),
relation,
userName,
teamNames,
filterRelation,
filter.getCondition(false));
}
@SqlQuery(
"SELECT count(id) FROM thread_entity "
+ "AND hash_id in (SELECT fromFQNHash FROM field_relationship WHERE "
+ "(:fqnPrefixHash IS NULL OR toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR toFQNHash=:fqnPrefixHash) AND fromType='THREAD' AND "
+ "(:toType IS NULL OR toType LIKE CONCAT(:toType, '.%') OR toType=:toType) AND relation= :relation) "
+ "AND (:userName IS NULL OR id in (SELECT toFQNHash FROM field_relationship WHERE "
+ " ((fromType='user' AND fromFQNHash= :userName) OR"
+ " (fromType='team' AND fromFQNHash IN ())) AND toType='THREAD' AND relation= :filterRelation) )")
int listCountThreadsByEntityLink(
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
@Bind("toType") String toType,
@Bind("relation") int relation,
@Bind("userName") String userName,
@BindList("teamNames") List teamNames,
@Bind("filterRelation") int filterRelation,
@Define("condition") String condition);
@ConnectionAwareSqlUpdate(
value = "UPDATE thread_entity SET json = :json where id = :id",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value = "UPDATE thread_entity SET json = (:json :: jsonb) where id = :id",
connectionType = POSTGRES)
void update(@BindUUID("id") UUID id, @Bind("json") String json);
@SqlQuery(
"SELECT entityLink, type, taskStatus, COUNT(id) as count FROM ( "
+ " SELECT te.entityLink, te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " WHERE hash_id IN ( "
+ " SELECT fromFQNHash FROM field_relationship "
+ " WHERE "
+ " (:fqnPrefixHash IS NULL OR toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR toFQNHash = :fqnPrefixHash) "
+ " AND fromType = 'THREAD' "
+ " AND (:toType IS NULL OR toType LIKE CONCAT(:toType, '.%') OR toType = :toType) "
+ " AND relation = 3 "
+ " ) "
+ " UNION "
+ " SELECT te.entityLink, te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " WHERE te.entityId = :entityId "
+ ") AS combined "
+ "GROUP BY type, taskStatus, entityLink")
@RegisterRowMapper(ThreadCountFieldMapper.class)
List> listCountByEntityLink(
@BindUUID("entityId") UUID entityId,
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
@Bind("toType") String toType);
@ConnectionAwareSqlQuery(
value =
"SELECT combined.type, combined.taskStatus, COUNT(combined.id) AS count "
+ "FROM ( "
+ " SELECT te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " JOIN entity_relationship er ON te.entityId = er.toId "
+ " WHERE "
+ " (er.fromEntity = 'user' AND er.fromId = :userId AND er.relation = 8 AND te.type <> 'Task') "
+ " OR (er.fromEntity = 'team' AND er.fromId IN () AND er.relation = 8 AND te.type <> 'Task') "
+ " UNION "
+ " SELECT te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " JOIN entity_relationship er ON te.id = er.toId "
+ " WHERE "
+ " er.fromEntity = 'user' AND er.fromId = :userId AND er.toEntity = 'THREAD' AND er.relation IN (1, 2) "
+ " UNION "
+ " SELECT te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " JOIN entity_relationship er ON te.id = er.toId "
+ " WHERE "
+ " (er.fromEntity = 'user' AND er.fromId = :userId AND er.relation = 11) "
+ " OR (er.fromEntity = 'team' AND er.fromId IN () AND er.relation = 11) "
+ " UNION "
+ " SELECT te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " WHERE te.createdBy = :username "
+ " UNION "
+ " SELECT te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " WHERE MATCH(te.taskAssigneesIds) AGAINST (:userTeamJsonMysql IN BOOLEAN MODE) "
+ ") AS combined WHERE combined.type is not NULL "
+ "GROUP BY combined.type, combined.taskStatus;",
connectionType = MYSQL)
@ConnectionAwareSqlQuery(
value =
"SELECT combined.type, combined.taskStatus, COUNT(combined.id) AS count "
+ "FROM ( "
+ " SELECT te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " JOIN entity_relationship er ON te.entityId = er.toId "
+ " WHERE "
+ " (er.fromEntity = 'user' AND er.fromId = :userId AND er.relation = 8 AND te.type <> 'Task') "
+ " OR (er.fromEntity = 'team' AND er.fromId IN () AND er.relation = 8 AND te.type <> 'Task') "
+ " UNION "
+ " SELECT te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " JOIN entity_relationship er ON te.id = er.toId "
+ " WHERE "
+ " er.fromEntity = 'user' AND er.fromId = :userId AND er.toEntity = 'THREAD' AND er.relation IN (1, 2) "
+ " UNION "
+ " SELECT te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " JOIN entity_relationship er ON te.id = er.toId "
+ " WHERE "
+ " (er.fromEntity = 'user' AND er.fromId = :userId AND er.relation = 11) "
+ " OR (er.fromEntity = 'team' AND er.fromId IN () AND er.relation = 11) "
+ " UNION "
+ " SELECT te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " WHERE te.createdBy = :username "
+ " UNION "
+ " SELECT te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " WHERE to_tsvector('simple', taskAssigneesIds) @@ to_tsquery('simple', :userTeamJsonPostgres) "
+ ") AS combined WHERE combined.type is not NULL "
+ "GROUP BY combined.type, combined.taskStatus;",
connectionType = POSTGRES)
@RegisterRowMapper(OwnerCountFieldMapper.class)
List> listCountByOwner(
@BindUUID("userId") UUID userId,
@BindList("teamIds") List teamIds,
@Bind("username") String username,
@Bind("userTeamJsonMysql") String userTeamJsonMysql,
@Bind("userTeamJsonPostgres") String userTeamJsonPostgres);
@SqlQuery(
"SELECT json FROM thread_entity AND "
+ "entityId in ("
+ "SELECT toId FROM entity_relationship WHERE "
+ "((fromEntity='user' AND fromId= :userId) OR "
+ "(fromEntity='team' AND fromId IN ())) AND relation= :relation) "
+ "ORDER BY createdAt DESC "
+ "LIMIT :limit")
List listThreadsByFollows(
@BindUUID("userId") UUID userId,
@BindList("teamIds") List teamIds,
@Bind("limit") int limit,
@Bind("relation") int relation,
@Define("condition") String condition);
@SqlQuery(
"SELECT count(id) FROM thread_entity AND "
+ "entityId in ("
+ "SELECT toId FROM entity_relationship WHERE "
+ "((fromEntity='user' AND fromId= :userId) OR "
+ "(fromEntity='team' AND fromId IN ())) AND relation= :relation)")
int listCountThreadsByFollows(
@BindUUID("userId") UUID userId,
@BindList("teamIds") List teamIds,
@Bind("relation") int relation,
@Define("condition") String condition);
@SqlQuery(
"SELECT json FROM ( "
+ " SELECT json, createdAt FROM thread_entity te "
+ " AND entityId IN ( "
+ " SELECT toId FROM entity_relationship er "
+ " WHERE er.relation = 8 "
+ " AND ( "
+ " (er.fromEntity = 'user' AND er.fromId = :userId) "
+ " OR (er.fromEntity = 'team' AND er.fromId IN ()) "
+ " ) "
+ " ) "
+ " UNION "
+ " SELECT json, createdAt FROM thread_entity te "
+ " AND id IN ( "
+ " SELECT toId FROM entity_relationship er "
+ " WHERE er.toEntity = 'THREAD' "
+ " AND er.relation IN (1, 2) "
+ " AND er.fromEntity = 'user' "
+ " AND er.fromId = :userId "
+ " ) "
+ " UNION "
+ " SELECT json, createdAt FROM thread_entity te "
+ " AND id IN ( "
+ " SELECT toId FROM entity_relationship er "
+ " WHERE er.relation = 11 "
+ " AND ( "
+ " (er.fromEntity = 'user' AND er.fromId = :userId) "
+ " OR (er.fromEntity = 'team' AND er.fromId IN ()) "
+ " ) "
+ " ) "
+ ") AS combined "
+ "ORDER BY createdAt DESC "
+ "LIMIT :limit")
List listThreadsByOwnerOrFollows(
@BindUUID("userId") UUID userId,
@BindList("teamIds") List teamIds,
@Bind("limit") int limit,
@Define("condition") String condition);
@SqlQuery(
"SELECT COUNT(id) FROM ( "
+ " SELECT te.id FROM thread_entity te "
+ " AND entityId IN ( "
+ " SELECT toId FROM entity_relationship er "
+ " WHERE er.relation = 8 "
+ " AND ( "
+ " (er.fromEntity = 'user' AND er.fromId = :userId) "
+ " OR (er.fromEntity = 'team' AND er.fromId IN ()) "
+ " ) "
+ " ) "
+ " UNION "
+ " SELECT te.id FROM thread_entity te "
+ " AND id IN ( "
+ " SELECT toId FROM entity_relationship er "
+ " WHERE er.toEntity = 'THREAD' "
+ " AND er.relation IN (1, 2) "
+ " AND er.fromEntity = 'user' "
+ " AND er.fromId = :userId "
+ " ) "
+ " UNION "
+ " SELECT te.id FROM thread_entity te "
+ " AND id IN ( "
+ " SELECT toId FROM entity_relationship er "
+ " WHERE er.relation = 11 "
+ " AND ( "
+ " (er.fromEntity = 'user' AND er.fromId = :userId) "
+ " OR (er.fromEntity = 'team' AND er.fromId IN ()) "
+ " ) "
+ " ) "
+ ") AS combined")
int listCountThreadsByOwnerOrFollows(
@BindUUID("userId") UUID userId,
@BindList("teamIds") List teamIds,
@Define("condition") String condition);
@SqlQuery(
"SELECT json FROM thread_entity AND "
+ "hash_id in ("
+ "SELECT toFQNHash FROM field_relationship WHERE "
+ "((fromType='user' AND fromFQNHash= :userName) OR "
+ "(fromType='team' AND fromFQNHash IN ())) AND toType='THREAD' AND relation= :relation) "
+ "ORDER BY createdAt DESC "
+ "LIMIT :limit")
List listThreadsByMentions(
@Bind("userName") String userName,
@BindList("teamNames") List teamNames,
@Bind("limit") int limit,
@Bind("relation") int relation,
@Define("condition") String condition);
@SqlQuery(
"SELECT count(id) FROM thread_entity AND "
+ "hash_id in ("
+ "SELECT toFQNHash FROM field_relationship WHERE "
+ "((fromType='user' AND fromFQNHash= :userName) OR "
+ "(fromType='team' AND fromFQNHash IN ())) AND toType='THREAD' AND relation= :relation) ")
int listCountThreadsByMentions(
@Bind("userName") String userName,
@BindList("teamNames") List teamNames,
@Bind("relation") int relation,
@Define("condition") String condition);
@SqlQuery(
"SELECT json FROM thread_entity "
+ "AND MD5(id) in (SELECT fromFQNHash FROM field_relationship WHERE "
+ "(:fqnPrefixHash IS NULL OR toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR toFQNHash=:fqnPrefixHash) AND fromType='THREAD' AND "
+ "((:toType1 IS NULL OR toType LIKE CONCAT(:toType1, '.%') OR toType=:toType1) OR "
+ "(:toType2 IS NULL OR toType LIKE CONCAT(:toType2, '.%') OR toType=:toType2)) AND relation= :relation)"
+ "AND (:userName IS NULL OR MD5(id) in (SELECT toFQNHash FROM field_relationship WHERE "
+ " ((fromType='user' AND fromFQNHash= :userName) OR"
+ " (fromType='team' AND fromFQNHash IN ())) AND toType='THREAD' AND relation= :filterRelation) )"
+ "ORDER BY createdAt DESC "
+ "LIMIT :limit")
List listThreadsByGlossaryAndTerms(
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
@Bind("toType1") String toType1,
@Bind("toType2") String toType2,
@Bind("limit") int limit,
@Bind("relation") int relation,
@BindFQN("userName") String userName,
@BindList("teamNames") List teamNames,
@Bind("filterRelation") int filterRelation,
@Define("condition") String condition);
default List> listCountThreadsByGlossaryAndTerms(
EntityLink entityLink, EntityReference reference) {
EntityLink glossaryTermLink =
new EntityLink(GLOSSARY_TERM, entityLink.getFullyQualifiedFieldValue());
return listCountThreadsByGlossaryAndTerms(
reference.getId(),
reference.getFullyQualifiedName(),
entityLink.getFullyQualifiedFieldType(),
glossaryTermLink.getFullyQualifiedFieldType());
}
@SqlQuery(
"SELECT entityLink, type, taskStatus, COUNT(id) as count "
+ "FROM ( "
+ " SELECT te.entityLink, te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " WHERE te.entityId = :entityId "
+ " UNION "
+ " SELECT te.entityLink, te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " WHERE te.hash_id IN ( "
+ " SELECT fr.fromFQNHash "
+ " FROM field_relationship fr "
+ " WHERE (:fqnPrefixHash IS NULL OR fr.toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR fr.toFQNHash = :fqnPrefixHash) "
+ " AND fr.fromType = 'THREAD' "
+ " AND (:toType1 IS NULL OR fr.toType LIKE CONCAT(:toType1, '.%') OR fr.toType = :toType1) "
+ " AND fr.relation = 3 "
+ " ) "
+ " UNION "
+ " SELECT te.entityLink, te.type, te.taskStatus, te.id "
+ " FROM thread_entity te "
+ " WHERE te.type = 'Task' "
+ " AND te.hash_id IN ( "
+ " SELECT fr.fromFQNHash "
+ " FROM field_relationship fr "
+ " JOIN thread_entity te2 ON te2.hash_id = fr.fromFQNHash WHERE fr.fromFQNHash = te.hash_id AND te2.type = 'Task' "
+ " AND (:fqnPrefixHash IS NULL OR fr.toFQNHash LIKE CONCAT(:fqnPrefixHash, '.%') OR fr.toFQNHash = :fqnPrefixHash) "
+ " AND fr.fromType = 'THREAD' "
+ " AND (:toType2 IS NULL OR fr.toType LIKE CONCAT(:toType2, '.%') OR fr.toType = :toType2) "
+ " AND fr.relation = 3 "
+ " ) "
+ ") AS combined_results "
+ "GROUP BY entityLink, type, taskStatus ")
@RegisterRowMapper(ThreadCountFieldMapper.class)
List> listCountThreadsByGlossaryAndTerms(
@BindUUID("entityId") UUID entityId,
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
@Bind("toType1") String toType1,
@Bind("toType2") String toType2);
@SqlQuery("select id from thread_entity where entityId = :entityId")
List findByEntityId(@Bind("entityId") String entityId);
@ConnectionAwareSqlUpdate(
value =
"UPDATE thread_entity SET json = JSON_SET(json, '$.about', :newEntityLink)\n"
+ "WHERE entityId = :entityId",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"UPDATE thread_entity SET json = jsonb_set(json, '{about}', to_jsonb(:newEntityLink::text), false)\n"
+ "WHERE entityId = :entityId",
connectionType = POSTGRES)
void updateByEntityId(
@Bind("newEntityLink") String newEntityLink, @Bind("entityId") String entityId);
class OwnerCountFieldMapper implements RowMapper> {
@Override
public List map(ResultSet rs, StatementContext ctx) throws SQLException {
return Arrays.asList(
rs.getString("type"), rs.getString("taskStatus"), rs.getString("count"));
}
}
class ThreadCountFieldMapper implements RowMapper> {
@Override
public List map(ResultSet rs, StatementContext ctx) throws SQLException {
return Arrays.asList(
rs.getString("entityLink"),
rs.getString("type"),
rs.getString("taskStatus"),
rs.getString("count"));
}
}
}
interface FieldRelationshipDAO {
@ConnectionAwareSqlUpdate(
value =
"INSERT IGNORE INTO field_relationship(fromFQNHash, toFQNHash, fromFQN, toFQN, fromType, toType, relation, json) "
+ "VALUES (:fromFQNHash, :toFQNHash, :fromFQN, :toFQN, :fromType, :toType, :relation, :json)",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO field_relationship(fromFQNHash, toFQNHash, fromFQN, toFQN, fromType, toType, relation, json) "
+ "VALUES (:fromFQNHash, :toFQNHash, :fromFQN, :toFQN, :fromType, :toType, :relation, (:json :: jsonb)) "
+ "ON CONFLICT (fromFQNHash, toFQNHash, relation) DO NOTHING",
connectionType = POSTGRES)
void insert(
@BindFQN("fromFQNHash") String fromFQNHash,
@BindFQN("toFQNHash") String toFQNHash,
@Bind("fromFQN") String fromFQN,
@Bind("toFQN") String toFQN,
@Bind("fromType") String fromType,
@Bind("toType") String toType,
@Bind("relation") int relation,
@Bind("json") String json);
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO field_relationship(fromFQNHash, toFQNHash, fromFQN, toFQN, fromType, toType, relation, jsonSchema, json) "
+ "VALUES (:fromFQNHash, :toFQNHash, :fromFQN, :toFQN, :fromType, :toType, :relation, :jsonSchema, :json) "
+ "ON DUPLICATE KEY UPDATE json = :json",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO field_relationship(fromFQNHash, toFQNHash, fromFQN, toFQN, fromType, toType, relation, jsonSchema, json) "
+ "VALUES (:fromFQNHash, :toFQNHash, :fromFQN, :toFQN, :fromType, :toType, :relation, :jsonSchema, (:json :: jsonb)) "
+ "ON CONFLICT (fromFQNHash, toFQNHash, relation) DO UPDATE SET json = EXCLUDED.json",
connectionType = POSTGRES)
void upsert(
@BindFQN("fromFQNHash") String fromFQNHash,
@BindFQN("toFQNHash") String toFQNHash,
@Bind("fromFQN") String fromFQN,
@Bind("toFQN") String toFQN,
@Bind("fromType") String fromType,
@Bind("toType") String toType,
@Bind("relation") int relation,
@Bind("jsonSchema") String jsonSchema,
@Bind("json") String json);
@SqlQuery(
"SELECT json FROM field_relationship WHERE "
+ "fromFQNHash = :fromFQNHash AND toFQNHash = :toFQNHash AND fromType = :fromType "
+ "AND toType = :toType AND relation = :relation")
String find(
@BindFQN("fromFQNHash") String fromFQNHash,
@BindFQN("toFQNHash") String toFQNHash,
@Bind("fromType") String fromType,
@Bind("toType") String toType,
@Bind("relation") int relation);
@SqlQuery(
"SELECT fromFQN, fromType, json FROM field_relationship WHERE "
+ "toFQNHash = :toFQNHash AND toType = :toType AND relation = :relation")
@RegisterRowMapper(FromFieldMapper.class)
List> findFrom(
@BindFQN("toFQNHash") String toFQNHash,
@Bind("toType") String toType,
@Bind("relation") int relation);
@SqlQuery(
"SELECT fromFQN, toFQN, json FROM field_relationship WHERE "
+ "fromFQNHash LIKE CONCAT(:fqnPrefixHash, '%') AND fromType = :fromType AND toType = :toType "
+ "AND relation = :relation")
@RegisterRowMapper(ToFieldMapper.class)
List> listToByPrefix(
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
@Bind("fromType") String fromType,
@Bind("toType") String toType,
@Bind("relation") int relation);
@Deprecated(since = "Release 1.1")
@SqlQuery(
"SELECT DISTINCT fromFQN, toFQN FROM field_relationship WHERE fromFQNHash = '' or fromFQNHash is null or toFQNHash = '' or toFQNHash is null LIMIT :limit")
@RegisterRowMapper(FieldRelationShipMapper.class)
List> migrationListDistinctWithOffset(@Bind("limit") int limit);
@SqlQuery(
"SELECT fromFQN, toFQN, json FROM field_relationship WHERE "
+ "fromFQNHash = :fqnHash AND fromType = :type AND toType = :otherType AND relation = :relation "
+ "UNION "
+ "SELECT toFQN, fromFQN, json FROM field_relationship WHERE "
+ "toFQNHash = :fqnHash AND toType = :type AND fromType = :otherType AND relation = :relation")
@RegisterRowMapper(ToFieldMapper.class)
List> listBidirectional(
@BindFQN("fqnHash") String fqnHash,
@Bind("type") String type,
@Bind("otherType") String otherType,
@Bind("relation") int relation);
@SqlQuery(
"SELECT fromFQN, toFQN, json FROM field_relationship WHERE "
+ "fromFQNHash LIKE CONCAT(:fqnPrefixHash, '%') AND fromType = :type AND toType = :otherType AND relation = :relation "
+ "UNION "
+ "SELECT toFQN, fromFQN, json FROM field_relationship WHERE "
+ "toFQNHash LIKE CONCAT(:fqnPrefixHash, '%') AND toType = :type AND fromType = :otherType AND relation = :relation")
@RegisterRowMapper(ToFieldMapper.class)
List> listBidirectionalByPrefix(
@BindFQN("fqnPrefixHash") String fqnPrefixHash,
@Bind("type") String type,
@Bind("otherType") String otherType,
@Bind("relation") int relation);
default void deleteAllByPrefix(String fqn) {
String prefix = String.format("%s%s%%", FullyQualifiedName.buildHash(fqn), Entity.SEPARATOR);
String condition = "WHERE (toFQNHash LIKE :prefix OR fromFQNHash LIKE :prefix)";
Map bindMap = new HashMap<>();
bindMap.put("prefix", prefix);
deleteAllByPrefixInternal(condition, bindMap);
}
@SqlUpdate("DELETE from field_relationship ")
void deleteAllByPrefixInternal(
@Define("cond") String cond, @BindMap Map bindings);
@SqlUpdate(
"DELETE from field_relationship WHERE fromFQNHash = :fromFQNHash AND toFQNHash = :toFQNHash AND fromType = :fromType "
+ "AND toType = :toType AND relation = :relation")
void delete(
@BindFQN("fromFQNHash") String fromFQNHash,
@BindFQN("toFQNHash") String toFQNHash,
@Bind("fromType") String fromType,
@Bind("toType") String toType,
@Bind("relation") int relation);
default void renameByToFQN(String oldToFQN, String newToFQN) {
renameByToFQNInternal(
oldToFQN,
FullyQualifiedName.buildHash(oldToFQN),
newToFQN,
FullyQualifiedName.buildHash(newToFQN)); // First rename targetFQN from oldFQN to newFQN
renameByToFQNPrefix(oldToFQN, newToFQN);
// Rename all the targetFQN prefixes starting with the oldFQN to newFQN
}
@SqlUpdate(
"Update field_relationship set toFQN = :newToFQN , toFQNHash = :newToFQNHash "
+ "where fromtype = 'THREAD' AND relation='3' AND toFQN = :oldToFQN and toFQNHash =:oldToFQNHash ;")
void renameByToFQNInternal(
@Bind("oldToFQN") String oldToFQN,
@Bind("oldToFQNHash") String oldToFQNHash,
@Bind("newToFQN") String newToFQN,
@Bind("newToFQNHash") String newToFQNHash);
default void renameByToFQNPrefix(String oldToFQNPrefix, String newToFQNPrefix) {
String update =
String.format(
"UPDATE field_relationship SET toFQN = REPLACE(toFQN, '%s.', '%s.') , toFQNHash = REPLACE(toFQNHash, '%s.', '%s.') where fromtype = 'THREAD' AND relation='3' AND toFQN like '%s.%%' and toFQNHash like '%s.%%' ",
escapeApostrophe(oldToFQNPrefix),
escapeApostrophe(newToFQNPrefix),
FullyQualifiedName.buildHash(oldToFQNPrefix),
FullyQualifiedName.buildHash(newToFQNPrefix),
escapeApostrophe(oldToFQNPrefix),
FullyQualifiedName.buildHash(oldToFQNPrefix));
renameByToFQNPrefixInternal(update);
}
@SqlUpdate("")
void renameByToFQNPrefixInternal(@Define("update") String update);
class FromFieldMapper implements RowMapper> {
@Override
public Triple map(ResultSet rs, StatementContext ctx)
throws SQLException {
return Triple.of(rs.getString("fromFQN"), rs.getString("fromType"), rs.getString("json"));
}
}
class ToFieldMapper implements RowMapper> {
@Override
public Triple map(ResultSet rs, StatementContext ctx)
throws SQLException {
return Triple.of(rs.getString("fromFQN"), rs.getString("toFQN"), rs.getString("json"));
}
}
class FieldRelationShipMapper implements RowMapper> {
@Override
public Pair map(ResultSet rs, StatementContext ctx) throws SQLException {
return Pair.of(rs.getString("fromFQN"), rs.getString("toFQN"));
}
}
@Getter
@Setter
class FieldRelationship {
private String fromFQNHash;
private String toFQNHash;
private String fromFQN;
private String toFQN;
private String fromType;
private String toType;
private int relation;
private String jsonSchema;
private String json;
}
}
interface BotDAO extends EntityDAO {
@Override
default String getTableName() {
return "bot_entity";
}
@Override
default Class getEntityClass() {
return Bot.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface DomainDAO extends EntityDAO {
@Override
default String getTableName() {
return "domain_entity";
}
@Override
default Class getEntityClass() {
return Domain.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
@Override
default boolean supportsSoftDelete() {
return false;
}
}
interface DataProductDAO extends EntityDAO {
@Override
default String getTableName() {
return "data_product_entity";
}
@Override
default Class getEntityClass() {
return DataProduct.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
@Override
default boolean supportsSoftDelete() {
return false;
}
}
interface EventSubscriptionDAO extends EntityDAO {
@Override
default String getTableName() {
return "event_subscription_entity";
}
@Override
default Class getEntityClass() {
return EventSubscription.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
@SqlQuery("SELECT json FROM event_subscription_entity")
List listAllEventsSubscriptions();
@Override
default boolean supportsSoftDelete() {
return false;
}
@SqlQuery("SELECT json FROM change_event_consumers where id = :id AND extension = :extension")
String getSubscriberExtension(@Bind("id") String id, @Bind("extension") String extension);
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO change_event_consumers(id, extension, jsonSchema, json) "
+ "VALUES (:id, :extension, :jsonSchema, :json)"
+ "ON DUPLICATE KEY UPDATE json = :json, jsonSchema = :jsonSchema",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO change_event_consumers(id, extension, jsonSchema, json) "
+ "VALUES (:id, :extension, :jsonSchema, (:json :: jsonb)) ON CONFLICT (id, extension) "
+ "DO UPDATE SET json = EXCLUDED.json, jsonSchema = EXCLUDED.jsonSchema",
connectionType = POSTGRES)
void upsertSubscriberExtension(
@Bind("id") String id,
@Bind("extension") String extension,
@Bind("jsonSchema") String jsonSchema,
@Bind("json") String json);
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO consumers_dlq(id, extension, json) "
+ "VALUES (:id, :extension, :json)"
+ "ON DUPLICATE KEY UPDATE json = :json",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO consumers_dlq(id, extension, json) "
+ "VALUES (:id, :extension, (:json :: jsonb)) ON CONFLICT (id, extension) "
+ "DO UPDATE SET json = EXCLUDED.json",
connectionType = POSTGRES)
void upsertFailedEvent(
@Bind("id") String id, @Bind("extension") String extension, @Bind("json") String json);
}
interface ChartDAO extends EntityDAO {
@Override
default String getTableName() {
return "chart_entity";
}
@Override
default Class getEntityClass() {
return Chart.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
}
interface ApplicationDAO extends EntityDAO {
@Override
default String getTableName() {
return "installed_apps";
}
@Override
default Class getEntityClass() {
return App.class;
}
}
interface ApplicationMarketPlaceDAO extends EntityDAO {
@Override
default String getTableName() {
return "apps_marketplace";
}
@Override
default Class getEntityClass() {
return AppMarketPlaceDefinition.class;
}
}
interface MessagingServiceDAO extends EntityDAO {
@Override
default String getTableName() {
return "messaging_service_entity";
}
@Override
default Class getEntityClass() {
return MessagingService.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface MetricsDAO extends EntityDAO {
@Override
default String getTableName() {
return "metric_entity";
}
@Override
default Class getEntityClass() {
return Metrics.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
}
interface MlModelDAO extends EntityDAO {
@Override
default String getTableName() {
return "ml_model_entity";
}
@Override
default Class getEntityClass() {
return MlModel.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
}
interface GlossaryDAO extends EntityDAO {
@Override
default String getTableName() {
return "glossary_entity";
}
@Override
default Class getEntityClass() {
return Glossary.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface GlossaryTermDAO extends EntityDAO {
@Override
default String getTableName() {
return "glossary_term_entity";
}
@Override
default Class getEntityClass() {
return GlossaryTerm.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
@Override
default int listCount(ListFilter filter) {
String condition = filter.getCondition();
String directChildrenOf = filter.getQueryParam("directChildrenOf");
if (!nullOrEmpty(directChildrenOf)) {
filter.queryParams.put(
"directChildrenOfHash", FullyQualifiedName.buildHash(directChildrenOf));
condition =
String.format(
" %s AND fqnHash = CONCAT(:directChildrenOfHash, '.', MD5(CASE WHEN name LIKE '%%.%%' THEN CONCAT('\"', name, '\"') ELSE name END)) ",
condition);
}
return listCount(getTableName(), getNameHashColumn(), filter.getQueryParams(), condition);
}
@Override
default List listBefore(
ListFilter filter, int limit, String beforeName, String beforeId) {
String condition = filter.getCondition();
String directChildrenOf = filter.getQueryParam("directChildrenOf");
if (!nullOrEmpty(directChildrenOf)) {
filter.queryParams.put(
"directChildrenOfHash", FullyQualifiedName.buildHash(directChildrenOf));
condition =
String.format(
" %s AND fqnHash = CONCAT(:directChildrenOfHash, '.', MD5(CASE WHEN name LIKE '%%.%%' THEN CONCAT('\"', name, '\"') ELSE name END)) ",
condition);
}
return listBefore(
getTableName(), filter.getQueryParams(), condition, limit, beforeName, beforeId);
}
@Override
default List listAfter(ListFilter filter, int limit, String afterName, String afterId) {
String condition = filter.getCondition();
String directChildrenOf = filter.getQueryParam("directChildrenOf");
if (!nullOrEmpty(directChildrenOf)) {
filter.queryParams.put(
"directChildrenOfHash", FullyQualifiedName.buildHash(directChildrenOf));
condition =
String.format(
" %s AND fqnHash = CONCAT(:directChildrenOfHash, '.', MD5(CASE WHEN name LIKE '%%.%%' THEN CONCAT('\"', name, '\"') ELSE name END)) ",
condition);
}
return listAfter(
getTableName(), filter.getQueryParams(), condition, limit, afterName, afterId);
}
@SqlQuery("select json FROM glossary_term_entity where fqnhash LIKE CONCAT(:fqnhash, '.%')")
List getNestedTerms(@BindFQN("fqnhash") String fqnhash);
}
interface IngestionPipelineDAO extends EntityDAO {
@Override
default String getTableName() {
return "ingestion_pipeline_entity";
}
@Override
default Class getEntityClass() {
return IngestionPipeline.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
@Override
default int listCount(ListFilter filter) {
String condition =
"INNER JOIN entity_relationship ON ingestion_pipeline_entity.id = entity_relationship.toId";
if (filter.getQueryParam("pipelineType") != null) {
String pipelineTypeCondition =
String.format(" and %s", filter.getPipelineTypeCondition(null));
condition += pipelineTypeCondition;
}
if (filter.getQueryParam("applicationType") != null) {
String applicationTypeCondition =
String.format(" and %s", filter.getApplicationTypeCondition());
condition += applicationTypeCondition;
}
if (filter.getQueryParam("service") != null) {
String serviceCondition = String.format(" and %s", filter.getServiceCondition(null));
condition += serviceCondition;
}
Map bindMap = new HashMap<>();
String serviceType = filter.getQueryParam("serviceType");
if (!nullOrEmpty(serviceType)) {
condition =
String.format(
"%s WHERE entity_relationship.fromEntity = :serviceType and entity_relationship.relation = :relation",
condition);
bindMap.put("relation", CONTAINS.ordinal());
return listIngestionPipelineCount(condition, bindMap, filter.getQueryParams());
}
return EntityDAO.super.listCount(filter);
}
@Override
default List listAfter(ListFilter filter, int limit, String afterName, String afterId) {
String condition =
"INNER JOIN entity_relationship ON ingestion_pipeline_entity.id = entity_relationship.toId";
if (filter.getQueryParam("pipelineType") != null) {
String pipelineTypeCondition =
String.format(" and %s", filter.getPipelineTypeCondition(null));
condition += pipelineTypeCondition;
}
if (filter.getQueryParam("applicationType") != null) {
String applicationTypeCondition =
String.format(" and %s", filter.getApplicationTypeCondition());
condition += applicationTypeCondition;
}
if (filter.getQueryParam("service") != null) {
String serviceCondition = String.format(" and %s", filter.getServiceCondition(null));
condition += serviceCondition;
}
Map bindMap = new HashMap<>();
String serviceType = filter.getQueryParam("serviceType");
if (!nullOrEmpty(serviceType)) {
condition =
String.format(
"%s WHERE entity_relationship.fromEntity = :serviceType and entity_relationship.relation = :relation and (ingestion_pipeline_entity.name > :afterName OR (ingestion_pipeline_entity.name = :afterName AND ingestion_pipeline_entity.id > :afterId)) order by ingestion_pipeline_entity.name ASC,ingestion_pipeline_entity.id ASC LIMIT :limit",
condition);
bindMap.put("relation", CONTAINS.ordinal());
bindMap.put("afterName", afterName);
bindMap.put("afterId", afterId);
bindMap.put("limit", limit);
return listAfterIngestionPipelineByserviceType(condition, bindMap, filter.getQueryParams());
}
return EntityDAO.super.listAfter(filter, limit, afterName, afterId);
}
@Override
default List listBefore(
ListFilter filter, int limit, String beforeName, String beforeId) {
String condition =
"INNER JOIN entity_relationship ON ingestion_pipeline_entity.id = entity_relationship.toId";
if (filter.getQueryParam("pipelineType") != null) {
String pipelineTypeCondition =
String.format(" and %s", filter.getPipelineTypeCondition(null));
condition += pipelineTypeCondition;
}
if (filter.getQueryParam("applicationType") != null) {
String applicationTypeCondition =
String.format(" and %s", filter.getApplicationTypeCondition());
condition += applicationTypeCondition;
}
if (filter.getQueryParam("service") != null) {
String serviceCondition = String.format(" and %s", filter.getServiceCondition(null));
condition += serviceCondition;
}
Map bindMap = new HashMap<>();
String serviceType = filter.getQueryParam("serviceType");
if (!nullOrEmpty(serviceType)) {
condition =
String.format(
"%s WHERE entity_relationship.fromEntity = :serviceType and entity_relationship.relation = :relation and (ingestion_pipeline_entity.name < :beforeName OR (ingestion_pipeline_entity.name = :beforeName AND ingestion_pipeline_entity.id < :beforeId)) order by ingestion_pipeline_entity.name DESC, ingestion_pipeline_entity.id DESC LIMIT :limit",
condition);
bindMap.put("relation", CONTAINS.ordinal());
bindMap.put("beforeName", beforeName);
bindMap.put("beforeId", beforeId);
bindMap.put("limit", limit);
return listBeforeIngestionPipelineByserviceType(
condition, bindMap, filter.getQueryParams());
}
return EntityDAO.super.listBefore(filter, limit, beforeName, beforeId);
}
@SqlQuery("SELECT ingestion_pipeline_entity.json FROM ingestion_pipeline_entity ")
List listAfterIngestionPipelineByserviceType(
@Define("cond") String cond,
@BindMap Map bindings,
@BindMap Map params);
@SqlQuery(
"SELECT json FROM (SELECT ingestion_pipeline_entity.name, ingestion_pipeline_entity.id, ingestion_pipeline_entity.json FROM ingestion_pipeline_entity ) last_rows_subquery ORDER BY last_rows_subquery.name,last_rows_subquery.id")
List listBeforeIngestionPipelineByserviceType(
@Define("cond") String cond,
@BindMap Map bindings,
@BindMap Map params);
@SqlQuery("SELECT count(*) FROM ingestion_pipeline_entity ")
int listIngestionPipelineCount(
@Define("cond") String cond,
@BindMap Map bindings,
@BindMap Map params);
}
interface PipelineServiceDAO extends EntityDAO {
@Override
default String getTableName() {
return "pipeline_service_entity";
}
@Override
default Class getEntityClass() {
return PipelineService.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface MlModelServiceDAO extends EntityDAO {
@Override
default String getTableName() {
return "mlmodel_service_entity";
}
@Override
default Class getEntityClass() {
return MlModelService.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface PolicyDAO extends EntityDAO {
@Override
default String getTableName() {
return "policy_entity";
}
@Override
default Class getEntityClass() {
return Policy.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
}
interface ReportDAO extends EntityDAO {
@Override
default String getTableName() {
return "report_entity";
}
@Override
default Class getEntityClass() {
return Report.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
}
interface TableDAO extends EntityDAO {
@Override
default String getTableName() {
return "table_entity";
}
@Override
default Class getEntityClass() {
return Table.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
@Override
default int listCount(ListFilter filter) {
String includeEmptyTestSuite = filter.getQueryParam("includeEmptyTestSuite");
if (includeEmptyTestSuite != null && !Boolean.parseBoolean(includeEmptyTestSuite)) {
String condition =
String.format(
"INNER JOIN entity_relationship er ON %s.id=er.fromId AND er.relation=%s AND er.toEntity='%s'",
getTableName(), CONTAINS.ordinal(), Entity.TEST_SUITE);
String mySqlCondition = condition;
String postgresCondition = condition;
mySqlCondition =
String.format("%s %s", mySqlCondition, filter.getCondition(getTableName()));
postgresCondition =
String.format("%s %s", postgresCondition, filter.getCondition(getTableName()));
return listCount(
getTableName(),
getNameHashColumn(),
filter.getQueryParams(),
mySqlCondition,
postgresCondition);
}
String condition = filter.getCondition(getTableName());
return listCount(
getTableName(), getNameHashColumn(), filter.getQueryParams(), condition, condition);
}
@Override
default List listBefore(
ListFilter filter, int limit, String beforeName, String beforeId) {
String includeEmptyTestSuite = filter.getQueryParam("includeEmptyTestSuite");
if (includeEmptyTestSuite != null && !Boolean.parseBoolean(includeEmptyTestSuite)) {
String condition =
String.format(
"INNER JOIN entity_relationship er ON %s.id=er.fromId AND er.relation=%s AND er.toEntity='%s'",
getTableName(), CONTAINS.ordinal(), Entity.TEST_SUITE);
String mySqlCondition = condition;
String postgresCondition = condition;
mySqlCondition =
String.format("%s %s", mySqlCondition, filter.getCondition(getTableName()));
postgresCondition =
String.format("%s %s", postgresCondition, filter.getCondition(getTableName()));
return listBefore(
getTableName(),
filter.getQueryParams(),
mySqlCondition,
postgresCondition,
limit,
beforeName,
beforeId);
}
String condition = filter.getCondition(getTableName());
return listBefore(
getTableName(),
filter.getQueryParams(),
condition,
condition,
limit,
beforeName,
beforeId);
}
@Override
default List listAfter(ListFilter filter, int limit, String afterName, String afterId) {
String includeEmptyTestSuite = filter.getQueryParam("includeEmptyTestSuite");
if (includeEmptyTestSuite != null && !Boolean.parseBoolean(includeEmptyTestSuite)) {
String condition =
String.format(
"INNER JOIN entity_relationship er ON %s.id=er.fromId AND er.relation=%s AND er.toEntity='%s'",
getTableName(), CONTAINS.ordinal(), Entity.TEST_SUITE);
String mySqlCondition = condition;
String postgresCondition = condition;
mySqlCondition =
String.format("%s %s", mySqlCondition, filter.getCondition(getTableName()));
postgresCondition =
String.format("%s %s", postgresCondition, filter.getCondition(getTableName()));
return listAfter(
getTableName(),
filter.getQueryParams(),
mySqlCondition,
postgresCondition,
limit,
afterName,
afterId);
}
String condition = filter.getCondition(getTableName());
return listAfter(
getTableName(), filter.getQueryParams(), condition, condition, limit, afterName, afterId);
}
}
interface StoredProcedureDAO extends EntityDAO {
@Override
default String getTableName() {
return "stored_procedure_entity";
}
@Override
default Class getEntityClass() {
return StoredProcedure.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
}
interface QueryDAO extends EntityDAO {
@Override
default String getTableName() {
return "query_entity";
}
@Override
default Class getEntityClass() {
return Query.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
@Override
default boolean supportsSoftDelete() {
return false;
}
@Override
default int listCount(ListFilter filter) {
String entityId = filter.getQueryParam("entityId");
String condition =
"INNER JOIN entity_relationship ON query_entity.id = entity_relationship.toId";
Map bindMap = new HashMap<>();
if (!nullOrEmpty(entityId)) {
condition =
String.format(
"%s WHERE entity_relationship.fromId = :id and entity_relationship.relation = :relation and entity_relationship.toEntity = :toEntityType",
condition);
bindMap.put("id", entityId);
bindMap.put("relation", MENTIONED_IN.ordinal());
bindMap.put("toEntityType", QUERY);
return listQueryCount(condition, bindMap);
}
return EntityDAO.super.listCount(filter);
}
@Override
default List listBefore(
ListFilter filter, int limit, String beforeName, String beforeId) {
String entityId = filter.getQueryParam("entityId");
String condition =
"INNER JOIN entity_relationship ON query_entity.id = entity_relationship.toId";
Map bindMap = new HashMap<>();
if (!nullOrEmpty(entityId)) {
condition =
String.format(
"%s WHERE entity_relationship.fromId = :entityId and entity_relationship.relation = :relation and entity_relationship.toEntity = :toEntity and (query_entity.name < :beforeName OR (query_entity.name = :beforeName AND query_entity.id < :beforeId)) order by query_entity.name DESC, query_entity.id DESC LIMIT :limit",
condition);
bindMap.put("entityId", entityId);
bindMap.put("relation", MENTIONED_IN.ordinal());
bindMap.put("toEntity", QUERY);
bindMap.put("beforeName", beforeName);
bindMap.put("beforeId", beforeId);
bindMap.put("limit", limit);
return listBeforeQueriesByEntityId(condition, bindMap);
}
return EntityDAO.super.listBefore(filter, limit, beforeName, beforeId);
}
@Override
default List listAfter(ListFilter filter, int limit, String afterName, String afterId) {
String entityId = filter.getQueryParam("entityId");
String condition =
"INNER JOIN entity_relationship ON query_entity.id = entity_relationship.toId";
Map bindMap = new HashMap<>();
if (!nullOrEmpty(entityId)) {
condition =
String.format(
"%s WHERE entity_relationship.fromId = :entityId and entity_relationship.relation = :relation and entity_relationship.toEntity = :toEntity and (query_entity.name > :afterName OR (query_entity.name = :afterName AND query_entity.name > :afterId)) order by query_entity.name ASC,query_entity.id ASC LIMIT :limit",
condition);
bindMap.put("entityId", entityId);
bindMap.put("relation", MENTIONED_IN.ordinal());
bindMap.put("toEntity", QUERY);
bindMap.put("afterName", afterName);
bindMap.put("afterId", afterId);
bindMap.put("limit", limit);
return listAfterQueriesByEntityId(condition, bindMap);
}
return EntityDAO.super.listAfter(filter, limit, afterName, afterId);
}
@SqlQuery("SELECT query_entity.json FROM query_entity ")
List listAfterQueriesByEntityId(
@Define("cond") String cond, @BindMap Map bindings);
@SqlQuery(
"SELECT json FROM (SELECT query_entity.name, query_entity.id, query_entity.json FROM query_entity ) last_rows_subquery ORDER BY name,id")
List listBeforeQueriesByEntityId(
@Define("cond") String cond, @BindMap Map bindings);
@SqlQuery("SELECT count(*) FROM query_entity ")
int listQueryCount(@Define("cond") String cond, @BindMap Map bindings);
}
interface PipelineDAO extends EntityDAO {
@Override
default String getTableName() {
return "pipeline_entity";
}
@Override
default Class getEntityClass() {
return Pipeline.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
}
interface ClassificationDAO extends EntityDAO {
@Override
default String getTableName() {
return "classification";
}
@Override
default Class getEntityClass() {
return Classification.class;
}
@Override
default String getNameHashColumn() {
return "nameHash";
}
}
interface TagDAO extends EntityDAO {
@Override
default String getTableName() {
return "tag";
}
@Override
default Class getEntityClass() {
return Tag.class;
}
@Override
default String getNameHashColumn() {
return "fqnHash";
}
@Override
default int listCount(ListFilter filter) {
boolean disabled = Boolean.parseBoolean(filter.getQueryParam("classification.disabled"));
String condition =
String.format(
"INNER JOIN entity_relationship er ON tag.id=er.toId AND er.relation=%s AND er.fromEntity='%s' "
+ "INNER JOIN classification c on er.fromId=c.id",
CONTAINS.ordinal(), Entity.CLASSIFICATION);
String mySqlCondition = condition;
String postgresCondition = condition;
if (disabled) {
mySqlCondition =
String.format(
"%s AND (JSON_EXTRACT(c.json, '$.disabled') IS NULL OR JSON_EXTRACT(c.json, '$.disabled') = TRUE)",
mySqlCondition);
postgresCondition =
String.format(
"%s AND ((c.json#>'{disabled}') IS NULL OR ((c.json#>'{disabled}')::boolean) = TRUE)",
postgresCondition);
} else {
mySqlCondition =
String.format(
"%s AND (JSON_EXTRACT(c.json, '$.disabled') IS NULL OR JSON_EXTRACT(c.json, '$.disabled') = FALSE)",
mySqlCondition);
postgresCondition =
String.format(
"%s AND ((c.json#>'{disabled}') IS NULL OR ((c.json#>'{disabled}')::boolean) = FALSE)",
postgresCondition);
}
mySqlCondition = String.format("%s %s", mySqlCondition, filter.getCondition("tag"));
postgresCondition = String.format("%s %s", postgresCondition, filter.getCondition("tag"));
return listCount(
getTableName(),
getNameHashColumn(),
filter.getQueryParams(),
mySqlCondition,
postgresCondition);
}
@Override
default List listBefore(
ListFilter filter, int limit, String beforeName, String beforeId) {
boolean disabled = Boolean.parseBoolean(filter.getQueryParam("classification.disabled"));
String condition =
String.format(
"INNER JOIN entity_relationship er ON tag.id=er.toId AND er.relation=%s AND er.fromEntity='%s' "
+ "INNER JOIN classification c on er.fromId=c.id",
CONTAINS.ordinal(), Entity.CLASSIFICATION);
String mySqlCondition = condition;
String postgresCondition = condition;
if (disabled) {
mySqlCondition =
String.format(
"%s AND (JSON_EXTRACT(c.json, '$.disabled') IS NULL OR JSON_EXTRACT(c.json, '$.disabled') = TRUE)",
mySqlCondition);
postgresCondition =
String.format(
"%s AND ((c.json#>'{disabled}') IS NULL OR ((c.json#>'{disabled}')::boolean) = TRUE)",
postgresCondition);
} else {
mySqlCondition =
String.format(
"%s AND (JSON_EXTRACT(c.json, '$.disabled') IS NULL OR JSON_EXTRACT(c.json, '$.disabled') = FALSE)",
mySqlCondition);
postgresCondition =
String.format(
"%s AND ((c.json#>'{disabled}') IS NULL OR ((c.json#>'{disabled}')::boolean) = FALSE)",
postgresCondition);
}
mySqlCondition = String.format("%s %s", mySqlCondition, filter.getCondition("tag"));
postgresCondition = String.format("%s %s", postgresCondition, filter.getCondition("tag"));
return listBefore(
getTableName(),
filter.getQueryParams(),
mySqlCondition,
postgresCondition,
limit,
beforeName,
beforeId);
}
@Override
default List listAfter(ListFilter filter, int limit, String afterName, String afterId) {
boolean disabled = Boolean.parseBoolean(filter.getQueryParam("classification.disabled"));
String condition =
String.format(
"INNER JOIN entity_relationship er ON tag.id=er.toId AND er.relation=%s AND er.fromEntity='%s' "
+ "INNER JOIN classification c on er.fromId=c.id",
CONTAINS.ordinal(), Entity.CLASSIFICATION);
String mySqlCondition = condition;
String postgresCondition = condition;
if (disabled) {
mySqlCondition =
String.format(
"%s AND (JSON_EXTRACT(c.json, '$.disabled') IS NULL OR JSON_EXTRACT(c.json, '$.disabled') = TRUE)",
mySqlCondition);
postgresCondition =
String.format(
"%s AND ((c.json#>'{disabled}') IS NULL OR ((c.json#>'{disabled}')::boolean) = TRUE)",
postgresCondition);
} else {
mySqlCondition =
String.format(
"%s AND (JSON_EXTRACT(c.json, '$.disabled') IS NULL OR JSON_EXTRACT(c.json, '$.disabled') = FALSE)",
mySqlCondition);
postgresCondition =
String.format(
"%s AND ((c.json#>'{disabled}') IS NULL OR ((c.json#>'{disabled}')::boolean) = FALSE)",
postgresCondition);
}
mySqlCondition = String.format("%s %s", mySqlCondition, filter.getCondition("tag"));
postgresCondition = String.format("%s %s", postgresCondition, filter.getCondition("tag"));
return listAfter(
getTableName(),
filter.getQueryParams(),
mySqlCondition,
postgresCondition,
limit,
afterName,
afterId);
}
@SqlQuery("select json FROM tag where fqnhash LIKE CONCAT(:fqnhash, '.%')")
List getTagsStartingWithPrefix(@BindFQN("fqnhash") String fqnhash);
}
@RegisterRowMapper(TagLabelMapper.class)
interface TagUsageDAO {
@ConnectionAwareSqlUpdate(
value =
"INSERT IGNORE INTO tag_usage (source, tagFQN, tagFQNHash, targetFQNHash, labelType, state) VALUES (:source, :tagFQN, :tagFQNHash, :targetFQNHash, :labelType, :state)",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO tag_usage (source, tagFQN, tagFQNHash, targetFQNHash, labelType, state) VALUES (:source, :tagFQN, :tagFQNHash, :targetFQNHash, :labelType, :state) ON CONFLICT (source, tagFQNHash, targetFQNHash) DO NOTHING",
connectionType = POSTGRES)
void applyTag(
@Bind("source") int source,
@Bind("tagFQN") String tagFQN,
@BindFQN("tagFQNHash") String tagFQNHash,
@BindFQN("targetFQNHash") String targetFQNHash,
@Bind("labelType") int labelType,
@Bind("state") int state);
default List getTags(String targetFQN) {
List tags = getTagsInternal(targetFQN);
tags.forEach(TagLabelUtil::applyTagCommonFields);
return tags;
}
default Map> getTagsByPrefix(
String targetFQNPrefix, String postfix, boolean requiresFqnHash) {
String fqnHash =
requiresFqnHash ? FullyQualifiedName.buildHash(targetFQNPrefix) : targetFQNPrefix;
Map> resultSet = new LinkedHashMap<>();
List> tags = getTagsInternalByPrefix(fqnHash, postfix);
tags.forEach(
pair -> {
String targetHash = pair.getLeft();
TagLabel tagLabel = pair.getRight();
List listOfTarget = new ArrayList<>();
if (resultSet.containsKey(targetHash)) {
listOfTarget = resultSet.get(targetHash);
listOfTarget.add(tagLabel);
} else {
listOfTarget.add(tagLabel);
}
resultSet.put(targetHash, listOfTarget);
});
return resultSet;
}
@SqlQuery(
"SELECT source, tagFQN, labelType, state FROM tag_usage WHERE targetFQNHash = :targetFQNHash ORDER BY tagFQN")
List getTagsInternal(@BindFQN("targetFQNHash") String targetFQNHash);
@ConnectionAwareSqlQuery(
value =
"SELECT source, tagFQN, labelType, targetFQNHash, state, json "
+ "FROM ("
+ " SELECT gterm.* , tu.* "
+ " FROM glossary_term_entity AS gterm "
+ " JOIN tag_usage AS tu "
+ " ON gterm.fqnHash = tu.tagFQNHash "
+ " WHERE tu.source = 1 "
+ " UNION ALL "
+ " SELECT ta.*, tu.* "
+ " FROM tag AS ta "
+ " JOIN tag_usage AS tu "
+ " ON ta.fqnHash = tu.tagFQNHash "
+ " WHERE tu.source = 0 "
+ ") AS combined_data "
+ "WHERE combined_data.targetFQNHash LIKE CONCAT(:targetFQNHashPrefix, :postfix)",
connectionType = MYSQL)
@ConnectionAwareSqlQuery(
value =
"SELECT source, tagFQN, labelType, targetFQNHash, state, json "
+ "FROM ("
+ " SELECT gterm.*, tu.* "
+ " FROM glossary_term_entity AS gterm "
+ " JOIN tag_usage AS tu ON gterm.fqnHash = tu.tagFQNHash "
+ " WHERE tu.source = 1 "
+ " UNION ALL "
+ " SELECT ta.*, tu.* "
+ " FROM tag AS ta "
+ " JOIN tag_usage AS tu ON ta.fqnHash = tu.tagFQNHash "
+ " WHERE tu.source = 0 "
+ ") AS combined_data "
+ "WHERE combined_data.targetFQNHash LIKE CONCAT(:targetFQNHashPrefix, :postfix)",
connectionType = POSTGRES)
@RegisterRowMapper(TagLabelRowMapperWithTargetFqnHash.class)
List> getTagsInternalByPrefix(
@Bind("targetFQNHashPrefix") String targetFQNHashPrefix, @Bind("postfix") String postfix);
@SqlQuery("SELECT * FROM tag_usage")
@Deprecated(since = "Release 1.1")
@RegisterRowMapper(TagLabelMapperMigration.class)
List listAll();
@SqlQuery(
"SELECT COUNT(*) FROM tag_usage "
+ "WHERE (tagFQNHash LIKE CONCAT(:tagFqnHash, '.%') OR tagFQNHash = :tagFqnHash) "
+ "AND source = :source")
int getTagCount(@Bind("source") int source, @BindFQN("tagFqnHash") String tagFqnHash);
@SqlUpdate("DELETE FROM tag_usage where targetFQNHash = :targetFQNHash")
void deleteTagsByTarget(@BindFQN("targetFQNHash") String targetFQNHash);
@SqlUpdate(
"DELETE FROM tag_usage where tagFQNHash = :tagFqnHash AND targetFQNHash LIKE CONCAT(:targetFQNHash, '%')")
void deleteTagsByTagAndTargetEntity(
@BindFQN("tagFqnHash") String tagFqnHash, @BindFQN("targetFQNHash") String targetFQNHash);
@SqlUpdate("DELETE FROM tag_usage where tagFQNHash = :tagFQNHash AND source = :source")
void deleteTagLabels(@Bind("source") int source, @BindFQN("tagFQNHash") String tagFQNHash);
@SqlUpdate("DELETE FROM tag_usage where tagFQNHash = :tagFQNHash")
void deleteTagLabelsByFqn(@BindFQN("tagFQNHash") String tagFQNHash);
@SqlUpdate(
"DELETE FROM tag_usage where targetFQNHash = :targetFQNHash OR targetFQNHash LIKE CONCAT(:targetFQNHash, '.%')")
void deleteTagLabelsByTargetPrefix(@BindFQN("targetFQNHash") String targetFQNHash);
@Deprecated(since = "Release 1.1")
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO tag_usage (source, tagFQN, tagFQNHash, targetFQNHash, labelType, state, targetFQN)"
+ "VALUES (:source, :tagFQN, :tagFQNHash, :targetFQNHash, :labelType, :state, :targetFQN) "
+ "ON DUPLICATE KEY UPDATE tagFQNHash = :tagFQNHash, targetFQNHash = :targetFQNHash",
connectionType = MYSQL)
@ConnectionAwareSqlUpdate(
value =
"INSERT INTO tag_usage (source, tagFQN, tagFQNHash, targetFQNHash, labelType, state, targetFQN) "
+ "VALUES (:source, :tagFQN, :tagFQNHash, :targetFQNHash, :labelType, :state, :targetFQN) "
+ "ON CONFLICT (source, tagFQN, targetFQN) "
+ "DO UPDATE SET tagFQNHash = EXCLUDED.tagFQNHash, targetFQNHash = EXCLUDED.targetFQNHash",
connectionType = POSTGRES)
void upsertFQNHash(
@Bind("source") int source,
@Bind("tagFQN") String tagFQN,
@Bind("tagFQNHash") String tagFQNHash,
@Bind("targetFQNHash") String targetFQNHash,
@Bind("labelType") int labelType,
@Bind("state") int state,
@Bind("targetFQN") String targetFQN);
/** Update all the tagFQN starting with oldPrefix to start with newPrefix due to tag or glossary name change */
default void updateTagPrefix(int source, String oldPrefix, String newPrefix) {
String update =
String.format(
"UPDATE tag_usage SET tagFQN = REPLACE(tagFQN, '%s.', '%s.'), tagFQNHash = REPLACE(tagFQNHash, '%s.', '%s.') WHERE source = %s AND tagFQNHash LIKE '%s.%%'",
escapeApostrophe(oldPrefix),
escapeApostrophe(newPrefix),
FullyQualifiedName.buildHash(oldPrefix),
FullyQualifiedName.buildHash(newPrefix),
source,
FullyQualifiedName.buildHash(oldPrefix));
updateTagPrefixInternal(update);
}
default void updateTargetFQNHashPrefix(
int source, String oldTargetFQNHashPrefix, String newTargetFQNHashPrefix) {
String update =
String.format(
"UPDATE tag_usage SET targetFQNHash = REPLACE(targetFQNHash, '%s.', '%s.') WHERE source = %s AND targetFQNHash LIKE '%s.%%'",
FullyQualifiedName.buildHash(oldTargetFQNHashPrefix),
FullyQualifiedName.buildHash(newTargetFQNHashPrefix),
source,
FullyQualifiedName.buildHash(oldTargetFQNHashPrefix));
updateTagPrefixInternal(update);
}
default void rename(int source, String oldFQN, String newFQN) {
renameInternal(source, oldFQN, newFQN, newFQN); // First rename tagFQN from oldFQN to newFQN
updateTagPrefix(
source, oldFQN,
newFQN); // Rename all the tagFQN prefixes starting with the oldFQN to newFQN
}
default void renameByTargetFQNHash(
int source, String oldTargetFQNHash, String newTargetFQNHash) {
updateTargetFQNHashPrefix(
source,
oldTargetFQNHash,
newTargetFQNHash); // Rename all the targetFQN prefixes starting with the oldFQN to newFQN
}
/** Rename the tagFQN */
@SqlUpdate(
"Update tag_usage set tagFQN = :newFQN, tagFQNHash = :newFQNHash WHERE source = :source AND tagFQNHash = :oldFQNHash")
void renameInternal(
@Bind("source") int source,
@BindFQN("oldFQNHash") String oldFQNHash,
@Bind("newFQN") String newFQN,
@BindFQN("newFQNHash") String newFQNHash);
@SqlUpdate("")
void updateTagPrefixInternal(@Define("update") String update);
@SqlQuery("select targetFQNHash FROM tag_usage where tagFQNHash = :tagFQNHash")
@RegisterRowMapper(TagLabelMapper.class)
List