com.torodb.backend.AbstractIdentifierConstraints Maven / Gradle / Ivy
/*
* ToroDB
* Copyright © 2014 8Kdata Technology (www.8kdata.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package com.torodb.backend;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.torodb.backend.meta.TorodbSchema;
import com.torodb.backend.tables.MetaDocPartTable.DocPartTableFields;
import com.torodb.core.backend.IdentifierConstraints;
import com.torodb.core.exceptions.SystemException;
import com.torodb.core.transaction.metainf.FieldType;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.inject.Singleton;
@Singleton
public abstract class AbstractIdentifierConstraints implements IdentifierConstraints {
private static final char SEPARATOR = '_';
private static final char ARRAY_DIMENSION_SEPARATOR = '$';
private final ImmutableMap fieldTypeIdentifiers;
private final ImmutableMap scalarFieldTypeIdentifiers;
private final ImmutableSet restrictedSchemaNames;
private final ImmutableSet restrictedColumnNames;
protected AbstractIdentifierConstraints(ImmutableSet restrictedSchemaNames,
ImmutableSet restrictedColumnNames) {
this.fieldTypeIdentifiers = Maps.immutableEnumMap(ImmutableMap.builder()
.put(FieldType.BINARY, 'r') // [r]aw bytes
.put(FieldType.BOOLEAN, 'b') // [b]oolean
.put(FieldType.DOUBLE, 'd') // [d]ouble float
.put(FieldType.INSTANT, 't') // [t]imestamp
.put(FieldType.INTEGER, 'i') // [i]nteger
.put(FieldType.LONG, 'l') // [l]ong
.put(FieldType.DECIMAL128, 'q') // [q]uad float
.put(FieldType.NULL, 'n') // [n]ull
.put(FieldType.STRING, 's') // [s]tring
.put(FieldType.CHILD, 'e') // child [e]lement
// Mongo types
.put(FieldType.MONGO_OBJECT_ID, 'x')
.put(FieldType.MONGO_TIME_STAMP, 'y')
// No-Mongo types
.put(FieldType.DATE, 'c') // [c]alendar
.put(FieldType.TIME, 'm') // ti[m]e
.put(FieldType.JAVASCRIPT, 'j') // [j]avascript
.put(FieldType.JAVASCRIPT_WITH_SCOPE, 'w') // javascript [w]ith scope
.put(FieldType.MIN_KEY, 'k') //min [k]ey
.put(FieldType.MAX_KEY, 'a') //m[a]x key
.put(FieldType.UNDEFINED, 'u') //[u]ndefined
.put(FieldType.MONGO_REGEX, 'g') //Re[g]Ex
.put(FieldType.MONGO_DB_POINTER, 'p') //DB [p]ointer
.put(FieldType.DEPRECATED, 'z') //running out of available chars; z means "the last".
.build());
//Letters left: f h o v
ImmutableMap.Builder scalarFieldTypeIdentifiersBuilder =
ImmutableMap.builder();
Set fieldTypeIdentifierSet = new HashSet<>();
for (FieldType fieldType : FieldType.values()) {
if (!this.fieldTypeIdentifiers.containsKey(fieldType)) {
throw new SystemException("FieldType " + fieldType
+ " has not been mapped to an identifier.");
}
char identifier = this.fieldTypeIdentifiers.get(fieldType);
if ((identifier < 'a' || identifier > 'z') && (identifier < '0' || identifier > '9')) {
throw new SystemException("FieldType " + fieldType + " has an unallowed identifier "
+ identifier);
}
if (fieldTypeIdentifierSet.contains(identifier)) {
throw new SystemException("FieldType " + fieldType + " identifier "
+ identifier + " was used by another FieldType.");
}
fieldTypeIdentifierSet.add(identifier);
scalarFieldTypeIdentifiersBuilder.put(fieldType, DocPartTableFields.SCALAR.fieldName
+ SEPARATOR + identifier);
}
this.scalarFieldTypeIdentifiers = Maps.immutableEnumMap(scalarFieldTypeIdentifiersBuilder
.build());
this.restrictedSchemaNames = ImmutableSet.builder()
.add(TorodbSchema.IDENTIFIER)
.addAll(restrictedSchemaNames)
.build();
this.restrictedColumnNames = ImmutableSet.builder()
.add(DocPartTableFields.DID.fieldName)
.add(DocPartTableFields.RID.fieldName)
.add(DocPartTableFields.PID.fieldName)
.add(DocPartTableFields.SEQ.fieldName)
.addAll(scalarFieldTypeIdentifiers.values())
.addAll(restrictedColumnNames)
.build();
}
@Override
public char getSeparator() {
return SEPARATOR;
}
@Override
public char getArrayDimensionSeparator() {
return ARRAY_DIMENSION_SEPARATOR;
}
@Override
public boolean isAllowedSchemaIdentifier(@Nonnull String schemaName) {
return !restrictedSchemaNames.contains(schemaName);
}
@Override
public boolean isAllowedTableIdentifier(@Nonnull String columnName) {
return true;
}
@Override
public boolean isAllowedColumnIdentifier(@Nonnull String columnName) {
return !restrictedColumnNames.contains(columnName);
}
@Override
public boolean isAllowedIndexIdentifier(@Nonnull String indexName) {
return true;
}
@Override
public boolean isSameIdentifier(@Nonnull String leftIdentifier, @Nonnull String rightIdentifier) {
return leftIdentifier.equals(rightIdentifier);
//leftIdentifier.toLowerCase(Locale.US).equals(rightIdentifier.toLowerCase(Locale.US));
}
@Override
public char getFieldTypeIdentifier(FieldType fieldType) {
return fieldTypeIdentifiers.get(fieldType);
}
@Override
public String getScalarIdentifier(FieldType fieldType) {
return scalarFieldTypeIdentifiers.get(fieldType);
}
}