/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.foundationdb.server.service.text;
import com.foundationdb.ais.model.Column;
import com.foundationdb.server.collation.AkCollator;
import com.foundationdb.server.types.TInstance;
import com.foundationdb.server.types.value.ValueSource;
import com.foundationdb.util.AkibanAppender;
import org.apache.lucene.document.DoubleField;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FloatField;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import java.sql.Types;
public class IndexedField
{
public static final String KEY_FIELD = ".hkey";
public static enum FieldType {
INT, LONG, FLOAT, DOUBLE, STRING, TEXT
}
private final Column column;
private final int position;
private final String name;
private final FieldType fieldType;
public IndexedField(Column column) {
this.column = column;
position = column.getPosition();
name = column.getName(); // TODO: Need to make unique among multiple tables.
switch (column.getType().typeClass().jdbcType()) {
case Types.TINYINT:
case Types.SMALLINT:
case Types.INTEGER:
fieldType = FieldType.INT;
break;
case Types.BIGINT:
fieldType = FieldType.LONG;
break;
case Types.FLOAT:
case Types.REAL:
fieldType = FieldType.FLOAT;
break;
case Types.DOUBLE:
fieldType = FieldType.DOUBLE;
break;
case Types.CHAR:
case Types.NVARCHAR:
case Types.VARCHAR:
{
AkCollator collator = column.getCollator();
if ((collator == null) || collator.isCaseSensitive()) {
fieldType = FieldType.STRING;
}
else {
fieldType = FieldType.TEXT;
}
}
break;
case Types.LONGNVARCHAR:
case Types.LONGVARCHAR:
case Types.NCHAR:
case Types.CLOB:
fieldType = FieldType.TEXT;
break;
default:
fieldType = FieldType.STRING;
break;
}
}
public Column getColumn() {
return column;
}
public int getPosition() {
return position;
}
public String getName() {
return name;
}
public boolean isCasePreserving() {
return (fieldType != FieldType.TEXT);
}
public Field getField(ValueSource value) {
if (value.isNull())
return null;
Field.Store store = Field.Store.NO; // Only store hkey.
switch (fieldType) {
case INT:
switch (TInstance.underlyingType(value.getType())) {
case INT_8:
return new IntField(name, value.getInt8(), store);
case INT_16:
return new IntField(name, value.getInt16(), store);
case UINT_16:
return new IntField(name, value.getUInt16(), store);
case INT_32:
default:
return new IntField(name, value.getInt32(), store);
}
case LONG:
return new LongField(name, value.getInt64(), store);
case FLOAT:
return new FloatField(name, value.getFloat(), store);
case DOUBLE:
return new DoubleField(name, value.getDouble(), store);
case STRING:
switch (TInstance.underlyingType(value.getType())) {
case STRING:
return new StringField(name, value.getString(), store);
default:
{
StringBuilder str = new StringBuilder();
value.getType().format(value, AkibanAppender.of(str));
return new StringField(name, str.toString(), store);
}
}
case TEXT:
return new TextField(name, value.getString(), store);
default:
return null;
}
}
@Override
public String toString() {
return name;
}
}