blob: 90f538008eda619f9a8995a5a09325270c97a465 [file] [log] [blame]
/*
* Copyright (c) 2010, Stanislav Muhametsin. All Rights Reserved.
*
* 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.
*/
package org.apache.zest.index.sql.support.postgresql;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import org.apache.zest.api.common.Optional;
import org.apache.zest.api.injection.scope.This;
import org.apache.zest.api.mixin.Mixins;
import org.apache.zest.index.sql.support.skeletons.SQLDBState;
/**
* A little helper interface to convert java types to SQL types when inserting objects to prepared statements. It will
* first preprocess the object and possibly convert it to something else (like Character to Integer). Then it will use
* the {@link SQLDBState#javaTypes2SQLTypes()} mapping to determine which SQL datatype to use when inserting the
* object to prepared statement.
*/
@Mixins( PostgreSQLTypeHelper.SQLTypeHelperMixin.class )
public interface PostgreSQLTypeHelper
{
/**
* Adds the specified object at specified index in specified prepared statement.
*
* @param ps The prepared statement.
* @param index The index for the object to be inserted in prepared statemtent ({@code > 0}).
* @param primitive The object to insert.
* @param primitiveType The type of object.
* @throws SQLException If something underlying throws it.
*/
void addPrimitiveToPS( PreparedStatement ps, Integer index, @Optional Object primitive, Type primitiveType )
throws SQLException;
Integer getSQLType( Object primitive );
public class SQLTypeHelperMixin
implements PostgreSQLTypeHelper
{
@This
private SQLDBState _state;
public Object processJavaPrimitiveBeforeUsingInStatement( Object primitive )
{
if( primitive != null )
{
if( primitive instanceof Character )
{
primitive = Character.codePointAt( new char[]
{
(Character) primitive
}, 0 );
}
else if( primitive instanceof Date )
{
primitive = new Timestamp( ( (Date) primitive ).getTime() );
}
else if( primitive instanceof Byte )
{
primitive = (short) (Byte) primitive;
}
else if( primitive instanceof Short )
{
primitive = (int) (Short) primitive;
}
}
return primitive;
}
@Override
public void addPrimitiveToPS( PreparedStatement ps, Integer index, Object primitive, Type primitiveType )
throws SQLException
{
primitive = processJavaPrimitiveBeforeUsingInStatement( primitive );
Integer sqlType = this.getSQLType( primitiveType );
ps.setObject( index, primitive, sqlType );
}
@Override
public Integer getSQLType( Object primitive )
{
primitive = processJavaPrimitiveBeforeUsingInStatement( primitive );
return this.getSQLType( primitive.getClass() );
}
private Integer getSQLType( Type primitiveType )
{
if( primitiveType instanceof ParameterizedType )
{
primitiveType = ( (ParameterizedType) primitiveType ).getRawType();
}
Class<?> primitiveClass = (Class<?>) primitiveType;
if( Enum.class.isAssignableFrom( primitiveClass ) )
{
primitiveClass = Enum.class;
}
Integer sqlType = this._state.javaTypes2SQLTypes().get().get( primitiveClass );
if( sqlType == null )
{
throw new InternalError( "Could not find mapping from " + primitiveClass + " to SQL type." );
}
return sqlType;
}
}
}