blob: 9907d1a2433f5900876ef37ce488b68033f9ddba [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ignite.internal.processors.cache.query;
import org.apache.ignite.Ignite;
import org.apache.ignite.cache.QueryIndexType;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
import org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor;
import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
import org.apache.ignite.internal.processors.task.GridInternal;
import org.apache.ignite.internal.util.typedef.C1;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.P1;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteCallable;
import org.apache.ignite.resources.IgniteInstanceResource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
/**
* Metadata job.
*/
@GridInternal
class GridCacheQuerySqlMetadataJobV2 implements IgniteCallable<Collection<GridCacheQueryManager.CacheSqlMetadata>> {
/** */
private static final long serialVersionUID = 0L;
/** Number of fields to report when no fields defined. Includes _key and _val columns. */
private static final int NO_FIELDS_COLUMNS_COUNT = 2;
/** Grid */
@IgniteInstanceResource
private Ignite ignite;
/** {@inheritDoc} */
@Override public Collection<GridCacheQueryManager.CacheSqlMetadata> call() {
final GridKernalContext ctx = ((IgniteKernal)ignite).context();
Collection<String> cacheNames = F.viewReadOnly(ctx.cache().caches(),
new C1<IgniteInternalCache<?, ?>, String>() {
@Override public String apply(IgniteInternalCache<?, ?> c) {
return c.name();
}
},
new P1<IgniteInternalCache<?, ?>>() {
@Override public boolean apply(IgniteInternalCache<?, ?> c) {
return !CU.isSystemCache(c.name()) && !DataStructuresProcessor.isDataStructureCache(c.name());
}
}
);
return F.transform(cacheNames, new C1<String, GridCacheQueryManager.CacheSqlMetadata>() {
@Override public GridCacheQueryManager.CacheSqlMetadata apply(String cacheName) {
Collection<GridQueryTypeDescriptor> types = ctx.query().types(cacheName);
Collection<String> names = U.newHashSet(types.size());
Map<String, String> keyClasses = U.newHashMap(types.size());
Map<String, String> valClasses = U.newHashMap(types.size());
Map<String, Map<String, String>> fields = U.newHashMap(types.size());
Map<String, Collection<GridCacheSqlIndexMetadata>> indexes = U.newHashMap(types.size());
Map<String, Set<String>> notNullFields = U.newHashMap(types.size());
for (GridQueryTypeDescriptor type : types) {
// Filter internal types (e.g., data structures).
if (type.name().startsWith("GridCache"))
continue;
names.add(type.name());
keyClasses.put(type.name(), type.keyClass().getName());
valClasses.put(type.name(), type.valueClass().getName());
int size = type.fields().isEmpty() ? NO_FIELDS_COLUMNS_COUNT : type.fields().size();
Map<String, String> fieldsMap = U.newLinkedHashMap(size);
HashSet<String> notNullFieldsSet = U.newHashSet(1);
// _KEY and _VAL are not included in GridIndexingTypeDescriptor.valueFields
if (type.fields().isEmpty()) {
fieldsMap.put("_KEY", type.keyClass().getName());
fieldsMap.put("_VAL", type.valueClass().getName());
}
for (Map.Entry<String, Class<?>> e : type.fields().entrySet()) {
String fieldName = e.getKey();
fieldsMap.put(fieldName.toUpperCase(), e.getValue().getName());
if (type.property(fieldName).notNull())
notNullFieldsSet.add(fieldName.toUpperCase());
}
fields.put(type.name(), fieldsMap);
notNullFields.put(type.name(), notNullFieldsSet);
Map<String, GridQueryIndexDescriptor> idxs = type.indexes();
Collection<GridCacheSqlIndexMetadata> indexesCol = new ArrayList<>(idxs.size());
for (Map.Entry<String, GridQueryIndexDescriptor> e : idxs.entrySet()) {
GridQueryIndexDescriptor desc = e.getValue();
// Add only SQL indexes.
if (desc.type() == QueryIndexType.SORTED) {
Collection<String> idxFields = new LinkedList<>();
Collection<String> descendings = new LinkedList<>();
for (String idxField : e.getValue().fields()) {
String idxFieldUpper = idxField.toUpperCase();
idxFields.add(idxFieldUpper);
if (desc.descending(idxField))
descendings.add(idxFieldUpper);
}
indexesCol.add(new GridCacheQueryManager.CacheSqlIndexMetadata(e.getKey().toUpperCase(),
idxFields, descendings, false));
}
}
indexes.put(type.name(), indexesCol);
}
return new GridCacheQuerySqlMetadataV2(cacheName, names, keyClasses, valClasses, fields, indexes,
notNullFields);
}
});
}
}