package com.basho.riak.presto.models; import com.facebook.presto.spi.ColumnHandle; import com.facebook.presto.spi.ColumnMetadata; import com.facebook.presto.spi.type.VarcharType; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import io.airlift.log.Logger; import java.util.List; import java.util.Map; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Strings.isNullOrEmpty; /** * Created by kuenishi on 2015/5/9. */ public class PRSubTable { /* * 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. */ public static final String SEPARATOR = "/"; private static final Logger log = Logger.get(PRTable.class); private final String name; private final String path; private final List<RiakColumn> columns; private String pkey; @JsonCreator public PRSubTable( @JsonProperty(value = "name", required = true) String name, @JsonProperty(value = "columns", required = true) List<RiakColumn> columns, @JsonProperty("path") String path) { checkArgument(!isNullOrEmpty(name), "name is null or is empty"); this.name = checkNotNull(name, "name is null"); this.path = checkNotNull(path, "Subtable can't be empty in subtable"); // should check whether valid JSONPath this.columns = ImmutableList.copyOf(checkNotNull(columns, "columns is null")); int index = 2; for (RiakColumn column : this.columns) { if (column.getPkey() && column.getType() == VarcharType.VARCHAR && this.pkey == null) { this.pkey = column.getName(); } } } public void setPkey(String k) { this.pkey = k; } public static Function<PRTable, String> nameGetter() { return new Function<PRTable, String>() { @Override public String apply(PRTable table) { return table.getName(); } }; } public String getFullName(PRTable parent) { return parent.getName() + SEPARATOR + name; } @JsonProperty public String getName() { return name; } @JsonProperty public String getPath() { return path; } @JsonProperty public List<RiakColumn> getColumns() { return columns; } public List<ColumnMetadata> getColumnsMetadata(String connectorId) { Map<String, ColumnHandle> columnHandles = getColumnHandles(connectorId); ImmutableList.Builder<ColumnMetadata> builder = ImmutableList.builder(); for (ColumnHandle columnHandle : columnHandles.values()) { RiakColumnHandle handle = (RiakColumnHandle) columnHandle; boolean hidden = false; if (handle.getOrdinalPosition() < 2) hidden = true; builder.add(new ColumnMetadata(handle.getColumn().getName(), handle.getColumn().getType(), handle.getColumn().getPkey(), handle.getColumn().getComment(), hidden)); } return builder.build(); } public Map<String, ColumnHandle> getColumnHandles(String connectorId) { //TODO: For now we assume keys are all in UTF-8 ImmutableMap.Builder<String, ColumnHandle> columnHandles = ImmutableMap.builder(); columnHandles.put(RiakColumnHandle.PKEY_COLUMN_NAME, new RiakColumnHandle(connectorId, new RiakColumn(RiakColumnHandle.PKEY_COLUMN_NAME, VarcharType.VARCHAR, pkey, true, true), 0)); //columnsMetadata.add(new ColumnMetadata(RiakColumnHandle.PKEY_COLUMN_NAME, VarcharType.VARCHAR, 0, true, pkey, true)); columnHandles.put(RiakColumnHandle.VTAG_COLUMN_NAME, new RiakColumnHandle(connectorId, new RiakColumn(RiakColumnHandle.VTAG_COLUMN_NAME, VarcharType.VARCHAR, "vtag", false, false), 1)); //columnsMetadata.add(new ColumnMetadata(RiakColumnHandle.VTAG_COLUMN_NAME, VarcharType.VARCHAR, 1, false, "vtag", true)); int index = 2; for (RiakColumn column : this.columns) { // Column metadata should remember which is primary key, but for now it's // impossible, as Presto database has no concept of primary key like this. columnHandles.put(column.getName(), new RiakColumnHandle(connectorId, column, index)); //columnsMetadata.add(new ColumnMetadata(column.getName(), column.getType(), // index, column.getIndex(), column.getComment(), false)); index++; } return columnHandles.build(); } public static String parentTableName(String s) { String[] parts = s.split(SEPARATOR); if (parts.length == 1) { return s; } else if (parts.length == 2) { return parts[0]; } else { throw new IllegalArgumentException(); } } public static String bucketName(String fullTableName) { return parentTableName(fullTableName); } // fullTableName is all lowercase, which came from schema // tableName is also lowercase, which came from schema public boolean match(String fullTableName) { String[] parts = fullTableName.split(SEPARATOR); if (parts.length == 1) { throw new IllegalArgumentException(); } else if (parts.length == 2) { return this.name.equals(parts[1]); } else { throw new IllegalArgumentException(); } } public String toString() { String ret = name + "(path= " + path + ", pkey=" + pkey + "):{"; for (RiakColumn col : columns) { ret += col.toString(); ret += " "; } ret += "} "; return ret; } }