/******************************************************************************* * Copyright (c) 2015 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Semantum Oy - initial API and implementation *******************************************************************************/ package org.simantics.db.indexing; import gnu.trove.map.hash.THashMap; import java.util.Collections; import java.util.EnumSet; import java.util.Map; import org.simantics.db.ReadGraph; import org.simantics.db.RequestProcessor; import org.simantics.db.Resource; import org.simantics.db.common.request.UniqueRead; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.RuntimeDatabaseException; import org.simantics.db.layer0.adapter.GenericRelation; import org.simantics.utils.datastructures.Pair; /** * @author Tuukka Lehtonen * @since 1.20.0, 1.18.4 */ class IndexSchema { public static enum Type { INT, LONG, FLOAT, DOUBLE, STRING, TEXT, } public static final EnumSet NUMERIC_TYPES = EnumSet.of(Type.INT, Type.LONG, Type.FLOAT, Type.DOUBLE); public final Pair[] fields; public final Map typeMap; /** * @param fields * @throws IllegalArgumentException * if any of the specified fields has an unsupported field type. * Supported field types are listed in enumeration {@link Type}. */ public IndexSchema(Pair[] fields) { this.fields = fields; Map typeMap = new THashMap<>(); for (Pair field : fields) { Type type = parseType(field); typeMap.put(field.first, type); } this.typeMap = Collections.unmodifiableMap(typeMap); } public boolean hasField(String fieldName) { return typeMap.get(fieldName) != null; } private static Type parseType(Pair field) { switch (field.second) { case "Int": return Type.INT; case "Long": return Type.LONG; case "Float": return Type.FLOAT; case "Double": return Type.DOUBLE; case "String": return Type.STRING; case "Text": return Type.TEXT; default: throw new IllegalArgumentException("Unrecognized index field type '" + field.second + "' for field '" + field.first + "'"); } } public static IndexSchema readFromRelation(RequestProcessor processor, final Resource relation) { try { return processor.syncRequest(new UniqueRead() { @Override public IndexSchema perform(ReadGraph graph) throws DatabaseException { return readFromRelation(graph, relation); } }); } catch (DatabaseException e) { throw new RuntimeDatabaseException(e); } } public static IndexSchema readFromRelation(ReadGraph graph, Resource relation) throws DatabaseException { try { GenericRelation r = graph.adapt(relation, GenericRelation.class); return new IndexSchema( r.getFields() ); } catch (IllegalArgumentException e) { throw new DatabaseException( "Failed to read index schema for relation " + relation + ". See cause for reason.", e); } } }