// Path: src/main/java/com/itranswarp/warpdb/util/ClassUtils.java
// public final class ClassUtils {
// 
// 	/**
// 	 * Scan @Entity classes in base packages.
// 	 * 
// 	 * @param basePackages
// 	 *            base package names.
// 	 * @return List of entity class.
// 	 */
// 	public static List<Class<?>> scanEntities(String... basePackages) {
// 		ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
// 		provider.addIncludeFilter(new AnnotationTypeFilter(Entity.class));
// 		List<Class<?>> classes = new ArrayList<>();
// 		for (String basePackage : basePackages) {
// 			Set<BeanDefinition> beans = provider.findCandidateComponents(basePackage);
// 			for (BeanDefinition bean : beans) {
// 				try {
// 					classes.add(Class.forName(bean.getBeanClassName()));
// 				} catch (ClassNotFoundException e) {
// 					throw new RuntimeException(e);
// 				}
// 			}
// 		}
// 		return classes;
// 	}
// 
// 	public static List<Type> getGenericInterfacesIncludeHierarchy(Class<?> clazz) {
// 		List<Type> list = new ArrayList<>();
// 		addGenericInterfaces(clazz, list);
// 		return list;
// 	}
// 
// 	static void addGenericInterfaces(Class<?> clazz, List<Type> list) {
// 		Type[] types = clazz.getGenericInterfaces();
// 		for (Type type : types) {
// 			list.add(type);
// 		}
// 		if (clazz.getSuperclass() != Object.class) {
// 			addGenericInterfaces(clazz.getSuperclass(), list);
// 		}
// 	}
// }


import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.function.Function;
import javax.annotation.PostConstruct;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import com.itranswarp.warpdb.util.ClassUtils;
			if (rs.next()) {
				return (Number) rs.getObject(1);
			}
			return null;
		}
	};
}

class BeanRowMapper<T> implements RowMapper<T> {

	// columnName -> property:
	final Map<String, AccessibleProperty> mapping;
	final Function<Void, T> constructor;

	BeanRowMapper(Class<T> clazz, List<AccessibleProperty> properties) {
		Map<String, AccessibleProperty> mapping = new HashMap<>();
		for (AccessibleProperty p : properties) {
			mapping.put(p.columnName.toLowerCase(), p);
		}
		this.mapping = mapping;
		try {
			Constructor<T> constructor = clazz.getDeclaredConstructor();
			constructor.setAccessible(true);
			this.constructor = (Void) -> {
				try {
					return constructor.newInstance();
				} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
					throw new RuntimeException(e);
				}
			};
// Path: src/main/java/com/itranswarp/warpdb/util/ClassUtils.java
// public final class ClassUtils {
// 
// 	/**
// 	 * Scan @Entity classes in base packages.
// 	 * 
// 	 * @param basePackages
// 	 *            base package names.
// 	 * @return List of entity class.
// 	 */
// 	public static List<Class<?>> scanEntities(String... basePackages) {
// 		ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
// 		provider.addIncludeFilter(new AnnotationTypeFilter(Entity.class));
// 		List<Class<?>> classes = new ArrayList<>();
// 		for (String basePackage : basePackages) {
// 			Set<BeanDefinition> beans = provider.findCandidateComponents(basePackage);
// 			for (BeanDefinition bean : beans) {
// 				try {
// 					classes.add(Class.forName(bean.getBeanClassName()));
// 				} catch (ClassNotFoundException e) {
// 					throw new RuntimeException(e);
// 				}
// 			}
// 		}
// 		return classes;
// 	}
// 
// 	public static List<Type> getGenericInterfacesIncludeHierarchy(Class<?> clazz) {
// 		List<Type> list = new ArrayList<>();
// 		addGenericInterfaces(clazz, list);
// 		return list;
// 	}
// 
// 	static void addGenericInterfaces(Class<?> clazz, List<Type> list) {
// 		Type[] types = clazz.getGenericInterfaces();
// 		for (Type type : types) {
// 			list.add(type);
// 		}
// 		if (clazz.getSuperclass() != Object.class) {
// 			addGenericInterfaces(clazz.getSuperclass(), list);
// 		}
// 	}
// }


// Path: src/main/java/com/itranswarp/warpdb/WarpDb.java
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.function.Function;
import javax.annotation.PostConstruct;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import com.itranswarp.warpdb.util.ClassUtils;

			if (rs.next()) {
				return (Number) rs.getObject(1);
			}
			return null;
		}
	};
}

class BeanRowMapper<T> implements RowMapper<T> {

	// columnName -> property:
	final Map<String, AccessibleProperty> mapping;
	final Function<Void, T> constructor;

	BeanRowMapper(Class<T> clazz, List<AccessibleProperty> properties) {
		Map<String, AccessibleProperty> mapping = new HashMap<>();
		for (AccessibleProperty p : properties) {
			mapping.put(p.columnName.toLowerCase(), p);
		}
		this.mapping = mapping;
		try {
			Constructor<T> constructor = clazz.getDeclaredConstructor();
			constructor.setAccessible(true);
			this.constructor = (Void) -> {
				try {
					return constructor.newInstance();
				} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
					throw new RuntimeException(e);
				}
			};
		} catch (NoSuchMethodException e) {