/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB Inc.
*
* VoltDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VoltDB 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VoltDB. If not, see <http://www.gnu.org/licenses/>.
*/
package org.voltdb.sysprocs.saverestore;
import java.text.ParseException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.voltdb.VoltTable;
import org.voltdb.VoltType;
import org.voltdb.VoltTypeException;
import org.voltdb.catalog.Column;
import org.voltdb.catalog.Table;
import org.voltdb.utils.CatalogUtil;
import org.voltdb.utils.VoltTypeUtil;
public abstract class SavedTableConverter
{
public static Boolean needsConversion(VoltTable inputTable,
Table outputTableSchema) {
for (int ii = 0; ii < inputTable.getColumnCount(); ii++) {
final String name = inputTable.getColumnName(ii);
final VoltType type = inputTable.getColumnType(ii);
final Column column = outputTableSchema.getColumns().get(name);
if (column == null) {
return true;
}
if (column.getIndex() != ii) {
return true;
}
if (column.getType() != type.getValue()) {
return true;
}
}
return false;
}
public static VoltTable convertTable(VoltTable inputTable,
Table outputTableSchema)
throws VoltTypeException
{
VoltTable new_table =
CatalogUtil.getVoltTable(outputTableSchema);
Map<Integer, Integer> column_copy_index_map =
computeColumnCopyIndexMap(inputTable, new_table);
// Copy all the old tuples into the new table
while (inputTable.advanceRow())
{
Object[] coerced_values =
new Object[new_table.getColumnCount()];
for (int i = 0; i < new_table.getColumnCount(); i++)
{
if (column_copy_index_map.containsKey(i))
{
int orig_column_index = column_copy_index_map.get(i);
coerced_values[i] =
inputTable.get(orig_column_index,
inputTable.getColumnType(orig_column_index));
}
else
{
// otherwise if it's nullable, insert null,
Column catalog_column =
outputTableSchema.getColumns().
get(new_table.getColumnName(i));
VoltType default_type =
VoltType.get((byte)catalog_column.getDefaulttype());
if (default_type != VoltType.INVALID)
{
// if there is a default value for this table/column
// insert the default value
try
{
coerced_values[i] =
VoltTypeUtil.
getObjectFromString(default_type,
catalog_column.
getDefaultvalue());
}
catch (ParseException e)
{
String message = "Column: ";
message += new_table.getColumnName(i);
message += " has an unparseable default: ";
message += catalog_column.getDefaultvalue();
message += " for VoltType: ";
message += default_type.toString();
throw new VoltTypeException(message);
}
}
else if (catalog_column.getNullable())
{
coerced_values[i] = null;
}
else
{
throw new VoltTypeException("Column: " +
new_table.getColumnName(i) +
" has no default " +
"and null is not permitted");
}
}
}
new_table.addRow(coerced_values);
}
return new_table;
}
/**
* @param origTable a table with the original saved-to-disk schema
* @param newTable a table with the current catalog schema
* @return a map of current schema column index to original
* schema column index.
*/
private static Map<Integer, Integer>
computeColumnCopyIndexMap(VoltTable origTable, VoltTable newTable)
{
Map<Integer, Integer> index_map = new HashMap<Integer, Integer>();
Set<String> old_column_names = getColumnNames(origTable);
Set<String> new_column_names = getColumnNames(newTable);
for (String name : new_column_names)
{
if (old_column_names.contains(name))
{
index_map.put(newTable.getColumnIndex(name),
origTable.getColumnIndex(name));
}
}
return index_map;
}
private static Set<String> getColumnNames(VoltTable table)
{
Set<String> names = new HashSet<String>();
int column_count = table.getColumnCount();
for (int i = 0; i < column_count; i++)
{
names.add(table.getColumnName(i));
}
return names;
}
// public static Object establishTableConversionNecessity(
// VoltTable inputTable,
// Table outputTableSchema) {
//
// }
}