package org.kroz.activerecord; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; /** * Defines DB schema definition statements from provided Java classes. <br/> * Use this class to specify structure of your DB. Call method addClass() for * each table and provide corresponding Java class. <br/> * Normally this class instantiated only once at the very beginning of the * application lifecycle. Once instantiated it is used by underlying * SQLDatabaseHelper and provides SQL statements for create or upgrade of DB * schema. * * @author JEREMYOT * @author Vladimir Kroz * <p>This project based on and inspired by 'androidactiverecord' project written by JEREMYOT</p> */ public class DatabaseBuilder { @SuppressWarnings("unchecked") Map<String, Class> classes = new HashMap<String, Class>(); String _dbName; /** * Create a new DatabaseBuilder for a database. */ public DatabaseBuilder(String dbName) { this._dbName = dbName; } /** * Add or update a table for an AREntity that is stored in the current * database. * * @param <T> * Any ActiveRecordBase type. * @param c * The class to reference when updating or adding a table. */ public <T extends ActiveRecordBase> void addClass(Class<T> c) { classes.put(c.getSimpleName(), c); } /** * Returns list of DB tables according to classes added to a schema map * * @return */ @SuppressWarnings("unchecked") public String[] getTables() { String[] ret = new String[classes.size()]; Class[] arr = new Class[classes.size()]; arr = classes.values().toArray(arr); for (int i = 0; i < arr.length; i++) { Class c = arr[i]; ret[i] = CamelNotationHelper.toSQLName(c.getSimpleName()); } return ret; } /** * Returns SQL create statement for specified table * * @param table * name in SQL notation * @throws ActiveRecordException */ @SuppressWarnings("unchecked") public <T extends ActiveRecordBase> String getSQLCreate(String table) throws ActiveRecordException { StringBuilder sb = null; Class<T> c = getClassBySqlName(table); T e = null; try { e = c.newInstance(); } catch (IllegalAccessException e1) { throw new ActiveRecordException(e1.getLocalizedMessage()); } catch (InstantiationException e1) { throw new ActiveRecordException(e1.getLocalizedMessage()); } if (null != c) { sb = new StringBuilder("CREATE TABLE ").append(table).append( " (_id integer primary key"); for (Field column : e.getColumnFieldsWithoutID()) { String jname = column.getName(); String qname = CamelNotationHelper.toSQLName(jname); Class<?> jtype = column.getType(); String qtype = Database.getSQLiteTypeString(jtype); sb.append(", ").append(qname).append(" ").append(qtype); } sb.append(")"); } return sb.toString(); } /** * Returns SQL drop table statement for specified table * * @param table * name in SQL notation */ public String getSQLDrop(String table) { return "DROP TABLE IF EXISTS " + table; } public String getDatabaseName() { return _dbName; } @SuppressWarnings("unchecked") private Class getClassBySqlName(String table) { String jName = CamelNotationHelper.toJavaClassName(table); return classes.get(jName); } }