1 /*******************************************************************************
2 * Copyright (c) 2015 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Semantum Oy - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.indexing;
14 import java.util.Collections;
15 import java.util.EnumSet;
18 import org.simantics.db.ReadGraph;
19 import org.simantics.db.RequestProcessor;
20 import org.simantics.db.Resource;
21 import org.simantics.db.common.request.UniqueRead;
22 import org.simantics.db.exception.DatabaseException;
23 import org.simantics.db.exception.RuntimeDatabaseException;
24 import org.simantics.db.indexing.exception.IndexingException;
25 import org.simantics.db.layer0.adapter.GenericRelation;
26 import org.simantics.utils.datastructures.Pair;
28 import gnu.trove.map.hash.THashMap;
31 * @author Tuukka Lehtonen
32 * @since 1.20.0, 1.18.4
36 public static enum Type {
45 public static final EnumSet<Type> NUMERIC_TYPES = EnumSet.of(Type.INT, Type.LONG, Type.FLOAT, Type.DOUBLE);
47 public final Pair<String, String>[] fields;
48 public final Map<String, Type> typeMap;
52 * @throws IllegalArgumentException
53 * if any of the specified fields has an unsupported field type.
54 * Supported field types are listed in enumeration {@link Type}.
56 public IndexSchema(Pair<String, String>[] fields) {
58 Map<String, Type> typeMap = new THashMap<>();
59 for (Pair<String, String> field : fields) {
60 Type type = parseType(field);
61 typeMap.put(field.first, type);
63 this.typeMap = Collections.unmodifiableMap(typeMap);
66 public boolean hasField(String fieldName) {
67 return typeMap.get(fieldName) != null;
70 private static Type parseType(Pair<String, String> field) {
71 switch (field.second) {
72 case "Int": return Type.INT;
73 case "Long": return Type.LONG;
74 case "Float": return Type.FLOAT;
75 case "Double": return Type.DOUBLE;
76 case "String": return Type.STRING;
77 case "Text": return Type.TEXT;
79 throw new IllegalArgumentException("Unrecognized index field type '" + field.second + "' for field '" + field.first + "'");
83 public static IndexSchema readFromRelation(RequestProcessor processor, final Resource relation) {
85 return processor.syncRequest(new UniqueRead<IndexSchema>() {
87 public IndexSchema perform(ReadGraph graph) throws DatabaseException {
88 return readFromRelation(graph, relation);
91 } catch (DatabaseException e) {
92 throw new RuntimeDatabaseException(e);
96 public static IndexSchema readFromRelation(ReadGraph graph, Resource relation) throws DatabaseException {
98 GenericRelation r = graph.adapt(relation, GenericRelation.class);
99 return new IndexSchema( r.getFields() );
100 } catch (IllegalArgumentException e) {
101 throw new IndexingException("Failed to read index schema for relation " + relation + ". See cause for reason.", e);