/** * Copyright 2015-2016 The OpenZipkin Authors * * 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 zipkin.storage.mysql; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import javax.sql.DataSource; import org.jooq.Condition; import org.jooq.Field; import org.jooq.Record; import org.jooq.Result; import org.jooq.Row2; import org.jooq.SelectOffsetStep; import zipkin.internal.Pair; import zipkin.storage.mysql.internal.generated.tables.ZipkinAnnotations; import static org.jooq.impl.DSL.row; import static zipkin.storage.mysql.internal.generated.tables.ZipkinAnnotations.ZIPKIN_ANNOTATIONS; import static zipkin.storage.mysql.internal.generated.tables.ZipkinSpans.ZIPKIN_SPANS; final class Schema { final List<Field<?>> spanIdFields; final List<Field<?>> spanFields; final List<Field<?>> annotationFields; final List<Field<?>> dependencyLinkFields; final List<Field<?>> dependencyLinkGroupByFields; final boolean hasTraceIdHigh; final boolean hasPreAggregatedDependencies; final boolean hasIpv6; Schema(DataSource datasource, DSLContexts context) { hasTraceIdHigh = HasTraceIdHigh.test(datasource, context); hasPreAggregatedDependencies = HasPreAggregatedDependencies.test(datasource, context); hasIpv6 = HasIpv6.test(datasource, context); spanIdFields = list(ZIPKIN_SPANS.TRACE_ID_HIGH, ZIPKIN_SPANS.TRACE_ID); spanFields = list(ZIPKIN_SPANS.fields()); annotationFields = list(ZIPKIN_ANNOTATIONS.fields()); dependencyLinkFields = list( ZIPKIN_SPANS.TRACE_ID_HIGH, ZIPKIN_SPANS.TRACE_ID, ZIPKIN_SPANS.PARENT_ID, ZIPKIN_SPANS.ID, ZIPKIN_ANNOTATIONS.A_KEY, ZIPKIN_ANNOTATIONS.ENDPOINT_SERVICE_NAME ); dependencyLinkGroupByFields = new ArrayList<>(dependencyLinkFields); dependencyLinkGroupByFields.remove(ZIPKIN_SPANS.PARENT_ID); if (!hasTraceIdHigh) { spanIdFields.remove(ZIPKIN_SPANS.TRACE_ID_HIGH); spanFields.remove(ZIPKIN_SPANS.TRACE_ID_HIGH); annotationFields.remove(ZIPKIN_ANNOTATIONS.TRACE_ID_HIGH); dependencyLinkFields.remove(ZIPKIN_SPANS.TRACE_ID_HIGH); dependencyLinkGroupByFields.remove(ZIPKIN_SPANS.TRACE_ID_HIGH); } if (!hasIpv6) { annotationFields.remove(ZIPKIN_ANNOTATIONS.ENDPOINT_IPV6); } } Condition joinCondition(ZipkinAnnotations annotationTable) { if (hasTraceIdHigh) { return ZIPKIN_SPANS.TRACE_ID_HIGH.eq(annotationTable.TRACE_ID_HIGH) .and(ZIPKIN_SPANS.TRACE_ID.eq(annotationTable.TRACE_ID)) .and(ZIPKIN_SPANS.ID.eq(annotationTable.SPAN_ID)); } else { return ZIPKIN_SPANS.TRACE_ID.eq(annotationTable.TRACE_ID) .and(ZIPKIN_SPANS.ID.eq(annotationTable.SPAN_ID)); } } /** Returns a mutable list */ static <T> List<T> list(T... elements) { return new ArrayList<>(Arrays.asList(elements)); } Condition spanTraceIdCondition(SelectOffsetStep<? extends Record> traceIdQuery) { if (hasTraceIdHigh) { Result<? extends Record> result = traceIdQuery.fetch(); List<Row2<Long, Long>> traceIds = new ArrayList<>(result.size()); for (Record r : result) { traceIds.add(row(r.get(ZIPKIN_SPANS.TRACE_ID_HIGH), r.get(ZIPKIN_SPANS.TRACE_ID))); } return row(ZIPKIN_SPANS.TRACE_ID_HIGH, ZIPKIN_SPANS.TRACE_ID).in(traceIds); } else { List<Long> traceIds = traceIdQuery.fetch(ZIPKIN_SPANS.TRACE_ID); return ZIPKIN_SPANS.TRACE_ID.in(traceIds); } } Condition spanTraceIdCondition(Long traceIdHigh, long traceIdLow) { return traceIdHigh != null && hasTraceIdHigh ? row(ZIPKIN_SPANS.TRACE_ID_HIGH, ZIPKIN_SPANS.TRACE_ID).eq(traceIdHigh, traceIdLow) : ZIPKIN_SPANS.TRACE_ID.eq(traceIdLow); } Condition annotationsTraceIdCondition(Set<Pair<Long>> traceIds) { boolean hasTraceIdHigh = false; for (Pair<Long> traceId : traceIds) { if (traceId._1 != 0) { hasTraceIdHigh = true; break; } } if (hasTraceIdHigh) { Row2[] result = new Row2[traceIds.size()]; int i = 0; for (Pair<Long> traceId128 : traceIds) { result[i++] = row(traceId128._1, traceId128._2); } return row(ZIPKIN_ANNOTATIONS.TRACE_ID_HIGH, ZIPKIN_ANNOTATIONS.TRACE_ID).in(result); } else { Long[] result = new Long[traceIds.size()]; int i = 0; for (Pair<Long> traceId128 : traceIds) { result[i++] = traceId128._2; } return ZIPKIN_ANNOTATIONS.TRACE_ID.in(result); } } }