package com.jqmobile.core.android.db.orm.table; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.jqmobile.core.android.db.orm.BaseDBColumn; import com.jqmobile.core.android.db.orm.BaseDBTable; import com.jqmobile.core.android.db.orm.ORMDBTable; import com.jqmobile.core.android.db.orm.base.ORMFactory; import com.jqmobile.core.orm.DBTable; import com.jqmobile.core.orm.ORM; import com.jqmobile.core.orm.TableUtil; import com.jqmobile.core.orm.exception.ORMException; import com.jqmobile.core.orm.exception.ORMNotDBTableException; import com.jqmobile.core.orm.exception.TableExitsException; import com.jqmobile.core.utils.plain.BeanUtils; import com.jqmobile.core.utils.plain.GUIDUtils; import com.jqmobile.core.utils.plain.Log; class BaseTableUtil implements TableUtil{ private SQLiteDatabase SQLiteDatabase; private Object lock = new Object(); private BaseTableUtil() { } private SQLiteDatabase getConnection() { return SQLiteDatabase; } private void setConnection(SQLiteDatabase SQLiteDatabase) { L10010: if(null == this.SQLiteDatabase || !this.SQLiteDatabase.isOpen()){ this.SQLiteDatabase = SQLiteDatabase; }else{ synchronized (lock) { try { lock.wait(1000); } catch (InterruptedException e) { } } break L10010; } // Log.getLog(getClass()).e(e); this.SQLiteDatabase = SQLiteDatabase; } private static BaseTableUtil util = new BaseTableUtil(); public static TableUtil getInstance(SQLiteDatabase conn) { util.setConnection(conn); return util; } @Override public void createTable(Class<?> c) throws ORMException { try { BaseDBTable param = BaseDBTable.getInstance(c); //当表已经存在的时候抛出异常 if(!valiTableExist(param.getTableName())){ BaseDBTable t = BaseDBTable.getInstance(c); getConnection().execSQL(t.getCreateTableSql()); insertORMDBTable(t); }else { throw new TableExitsException("表已存在"); } } catch (TableExitsException e) { e.printStackTrace(); } } /** * 获取表名 * @param c * @return */ @SuppressWarnings("unused") private String getTableName(Class<?> c) { return c.getAnnotation(DBTable.class).name()!=null ? c.getAnnotation(DBTable.class).name() : c.getName().substring(c.getName().lastIndexOf(".")+1,c.getName().length()-1); } private void insertORMDBTable(BaseDBTable t) throws ORMNotDBTableException, ORMException { if(t.getTableClass().equals(ORMDBTable.class)){ return; } // 修改表记录 ORM<ORMDBTable> orm = ORMFactory.instance(getConnection(), ORMDBTable.class); ORMDBTable sdt = new ORMDBTable(); sdt.setClassUrl(t.getTableClass().getName()); sdt.setName(t.getTableName()); sdt.setRecid(GUIDUtils.getUUIDByText(sdt.getName())); int oldVersion=orm.find(GUIDUtils.getUUIDByText(sdt.getName())).getVersion(); int versionNum=orm.delete(GUIDUtils.getUUIDByText(sdt.getName())); if(versionNum>0){ sdt.setVersion(oldVersion+1); }else{ sdt.setVersion(t.getDBTable().version()); } orm.insert(sdt); } @Override public void updateTable(Class<?> c) throws ORMException { BaseDBTable param = BaseDBTable.getInstance(c); // if not find table, create table. if (!valiTableExist(param.getTableName())) { createTable(c); } else { Cursor rs = getConnection().rawQuery("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE table_name = ?", new String[]{param.getTableName()}); List<String> oldColumn = new ArrayList<String>(); List<Field> newColumn = new ArrayList<Field>(); try { for(rs.moveToFirst();!rs.isAfterLast();rs.moveToNext()){ oldColumn.add(rs.getString(0)); } } finally { rs.close(); } Field[] fields = BeanUtils.getAllFields_Cache(c); // 20130705 List<Field> oldFields = new ArrayList<Field>(); // for (Field field : fields) { if(field.getName().contains("$")) continue; BaseDBColumn lable = BaseDBColumn.getInstance(field); if(!lable.isMapping()) continue; String columnName = lable.getColumnName(); if (!oldColumn.contains(columnName) && !oldColumn.contains(columnName.toUpperCase())) { newColumn.add(field); } // 20130705 else { oldFields.add(field); } // } if (!newColumn.isEmpty()) { // (加入字段) StringBuilder sql = new StringBuilder("ALTER TABLE ");// SaasDBTable // ADD // sex // BOOLEAN // ") sql.append(param.getTableName()); String columnName, columnType; for (int i = 0; i < newColumn.size(); i++) { sql.append(" ADD "); BaseDBColumn column = BaseDBColumn.getInstance(newColumn.get(i)); columnName = column.getColumnName(); columnType = column.getColumnType(); // sql.append(" "); sql.append(columnName); sql.append(" "); sql.append(columnType); // sql.append(" "); // sql.append(param.getColumnOther(newColumn.get(i), // c, columnType, columnName)); if (i != newColumn.size() - 1) sql.append(", \n"); } getConnection().execSQL(sql.toString()); } // 20130705(修改字段属性 if (!oldFields.isEmpty()) { // alter table user MODIFY new1 VARCHAR(10); StringBuilder sql = new StringBuilder("ALTER TABLE "); sql.append(param.getTableName()); String columnName, columnType; for (int i = 0; i < oldFields.size(); i++) { sql.append(" MODIFY "); BaseDBColumn column = BaseDBColumn.getInstance(newColumn.get(i)); columnName = column.getColumnName(); columnType = column.getColumnType(); // sql.append(" "); sql.append(columnName); sql.append(" "); sql.append(columnType); // sql.append(" "); // sql.append(param.getColumnOther(oldFields.get(i), // lable, columnType, columnName)); if (i != oldFields.size() - 1) sql.append(", \n"); } getConnection().execSQL(sql.toString()); } // 修改表记录 ORM<ORMDBTable> orm = ORMFactory.instance(getConnection(), ORMDBTable.class); ORMDBTable sdt = new ORMDBTable(); sdt.setClassUrl(c.getName()); sdt.setName(param.getTableName()); sdt.setRecid(GUIDUtils.getUUIDByText(sdt.getName())); sdt.setVersion(param.getDBTable().version()); orm.update(sdt); } } @Override public void autoUpdateAllTables() throws ORMException { ORM<ORMDBTable> orm = ORMFactory.instance(getConnection(), ORMDBTable.class); List<ORMDBTable> tables = orm.getAll(); Class<?> c; for (ORMDBTable t : tables) { try { c = Class.forName(t.getClassUrl(), true, Thread .currentThread().getContextClassLoader()); } catch (ClassNotFoundException e) { Log.getLog(this).w(e); continue; } if (!valiTableExist(t.getName())) { createTable(c); } else if (BaseDBTable.getInstance(c).getDBTable().version() > t .getVersion()) { updateTable(c); } } } /** * 自动建表 */ @Override public void autoUpdateTable(Class<?> c) throws ORMException { BaseDBTable param = BaseDBTable.getInstance(c); // if not find table, create table. if (!valiTableExist(param.getTableName())) { createTable(c); return; } // if have new version, update table. if (param.getDBTable().version() > 0) { ORM<ORMDBTable> orm = ORMFactory.instance(getConnection(), ORMDBTable.class); ORMDBTable table = orm.find(GUIDUtils .getUUIDByText(param.getTableName())); if (null == table) { table = new ORMDBTable(c); orm.insert(table); updateTable(c); } else if (param.getDBTable().version() > table .getVersion()) { updateTable(c); } } } @Override public boolean valiTableExist(String tableName) { Cursor rs = getConnection().rawQuery("SHOW TABLES LIKE ?", null); try { return 0 < rs.getCount(); } finally { rs.close(); } } @Override public void createMiddleTable(Class<?> c, Class<?> childClass) throws ORMException { } }