package org.codefilarete.stalactite.dsl.key;

import org.codefilarete.stalactite.dsl.naming.ColumnNamingStrategy;
import org.codefilarete.stalactite.sql.ddl.Size;
import org.codefilarete.stalactite.sql.ddl.structure.Column;
import org.codefilarete.stalactite.sql.ddl.structure.Table;

/**
 * Options on a key property
 *
 * @author Guillaume Mary
 */
public interface PropertyOptions<I> {
	
	/**
	 * Sets column name to be used. By default, column name is deduced from property name (it is deduced from
	 * property accessor), this method overwrites {@link ColumnNamingStrategy} for this property as well as field name
	 * (see {@link #fieldName(String)}.
	 */
	PropertyOptions<I> columnName(String name);
	
	/**
	 * Sets column size to be used.
	 */
	PropertyOptions<I> columnSize(Size size);
	
	/**
	 * Sets column to be used. Used to target a specific {@link Column} took on a {@link Table} created upstream.
	 * Allows to overwrite {@link ColumnNamingStrategy} as well as column Java type for this property (and maybe
	 * column property SQL type if you registered it to dialect {@link org.codefilarete.stalactite.sql.statement.binder.ColumnBinderRegistry}.
	 * This also sets {@link Table} to be used by mapping.
	 *
	 * @param column {@link Column} to be written and read by this property
	 */
	PropertyOptions<I> column(Column<? extends Table, ? extends I> column);
	
	/**
	 * Sets {@link java.lang.reflect.Field} name targeted by this property. Overwrites default mechanism which
	 * deduces it from accessor name.
	 * Uses it if your accessor doesn't follow bean naming convention.
	 * Field name will be used as column name except if {@link #columnName(String)} is used, it also overwrites
	 * {@link ColumnNamingStrategy} for this property.
	 *
	 * @param name {@link java.lang.reflect.Field} name that stores property value
	 */
	PropertyOptions<I> fieldName(String name);
}
