package org.yamcs.yarch; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class TupleDefinition implements Serializable, Cloneable { private static final long serialVersionUID = 200805301445L; private ArrayList<ColumnDefinition> columnDefinitions = new ArrayList<ColumnDefinition>(); private HashMap<String,Integer> columnNameIndex = new HashMap<String,Integer>(); public static final int MAX_COLS = 32000; public List<ColumnDefinition> getColumnDefinitions() { return columnDefinitions; } public void addColumn(String name, DataType type) { ColumnDefinition c = new ColumnDefinition(name,type); addColumn(c); } public void addColumn(ColumnDefinition c) { if(columnNameIndex.containsKey(c.getName())) { throw new IllegalArgumentException("Tuple has already a column '"+c.getName()+"'"); } columnDefinitions.add(c); columnNameIndex.put(c.getName(), columnDefinitions.size()-1); } /** * returns the index of the column with name or -1 if there is no such column * * @param name * @return the index of the column with name or -1 if there is no such column */ public int getColumnIndex(String name) { Integer i = columnNameIndex.get(name); if(i==null) { return -1; } else { return i; } } public boolean hasColumn(String name) { return columnNameIndex.containsKey(name); } /** * Get a column definition by name * * @param name * @return the column definition of the named column or null if the table does not have a column by that name */ public ColumnDefinition getColumn(String name) { Integer i = columnNameIndex.get(name); if(i==null) { return null; } else { return columnDefinitions.get(i); } } public ColumnDefinition getColumn(int index) { return columnDefinitions.get(index); } /** * renames the column - this should not be used when the tuple is in used as there is no synchronization around it. * * @param oldName * @param newName */ void renameColumn(String oldName, String newName) { int idx = columnNameIndex.remove(oldName); ColumnDefinition oldCd = columnDefinitions.get(idx); ColumnDefinition newCd = new ColumnDefinition(newName, oldCd.type); columnDefinitions.set(idx, newCd); columnNameIndex.put(newName, idx); } /** * Reads a tuple from an IO inputStream(socket). * @param inputStream * @return * @throws IOException public Tuple read(java.io.DataInput inputStream) throws IOException { Object[] columns=new Object[getColumnDefinitions().size()]; int i=0; for(ColumnDefinition cd:getColumnDefinitions()) { columns[i]=cd.deserialize(inputStream); if(columns[i]==null) { return null; } i++; } return new Tuple(this,columns); } public void write(java.io.DataOutputStream outputStream, Tuple t) throws IOException { for(ColumnDefinition cd:columnDefinitions) { cd.serialize(outputStream,t.getColumn(cd.getName())); } } */ /** * Returns a string "(col1 type, col2 type2, ....)" * suitable to be used in create stream * */ public String getStringDefinition() { StringBuilder sb=new StringBuilder(); sb.append("("); boolean first=true; for(ColumnDefinition cd:getColumnDefinitions()) { if(!first) { sb.append(", "); } else first=false; sb.append(cd.getStringDefinition()); } sb.append(")"); return sb.toString(); } /** * Returns a string "col1 type, col2 type2, ...." * (without parenthesis) suitable to be used in create table * */ public String getStringDefinition1() { StringBuilder sb = new StringBuilder(); boolean first=true; for(ColumnDefinition cd:getColumnDefinitions()) { if(!first) { sb.append(", "); } else first=false; sb.append(cd.toString()); } return sb.toString(); } /** * * @return number of columns part of the tuple */ public int size() { return columnDefinitions.size(); } /** * * @return a copy of the tuple definition that can be used to add columns */ public TupleDefinition copy() { TupleDefinition ntd=new TupleDefinition(); ntd.columnDefinitions.addAll(columnDefinitions); ntd.columnNameIndex.putAll(columnNameIndex); return ntd; } @Override public String toString() { return getStringDefinition(); } }