Permalink
Browse files

Merge branch 'track-tables'

  • Loading branch information...
mick88 committed Oct 16, 2013
2 parents 05e68c5 + b6466e2 commit 313e1f3f034b420f1668b222b80bed57117f39c1
@@ -5,6 +5,7 @@
{
// Class field types
public final static int
TYPE_NA = -1,
TYPE_OTHER = 100,
TYPE_STRING = 101,
TYPE_COLLECTION = 102,
@@ -2,6 +2,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import android.annotation.TargetApi;
@@ -12,15 +13,22 @@
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.location.Address;
import android.os.Build;
import android.util.Log;
import com.michaldabski.msqlite.models.Table;
import com.michaldabski.msqlite.queries.CreateTable;
import com.michaldabski.msqlite.queries.Drop;
public abstract class MSQLiteOpenHelper extends SQLiteOpenHelper
{
/**
* collection of classes that will be automatically converted to database tables in on create
* and upgraded in opUpgrade
*/
private final Collection<Class<?>> classes = new HashSet<Class<?>>();
// Constructors
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public MSQLiteOpenHelper(Context context, String name, CursorFactory factory,
@@ -32,12 +40,106 @@ public MSQLiteOpenHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}
public MSQLiteOpenHelper(Context context, String name, CursorFactory factory,
int version, Collection<Class<?>> trackedClasses)
{
this(context, name, factory, version);
trackClasses(trackedClasses);
}
public MSQLiteOpenHelper(Context context, String name, CursorFactory factory,
int version, Class<?>[] trackedClasses)
{
this(context, name, factory, version);
trackClasses(trackedClasses);
}
// Static methods
public static void createTable(SQLiteDatabase database, Class<?> type, boolean ifNotExist)
{
createTable(database, new Table(type), ifNotExist);
}
public static void createTable(SQLiteDatabase database, Table table, boolean ifNotExist)
{
database
.execSQL(new CreateTable(type).setIF_NOT_EXIST(ifNotExist).build());
.execSQL(new CreateTable(table).setIF_NOT_EXIST(ifNotExist).build());
}
private static void upgradeTable(SQLiteDatabase database, Table table)
{
Cursor cursor = database.rawQuery("PRAGMA table_info("+table.getName()+");", null);
if (cursor.getCount() == 0)
{
createTable(database, table, false);
Log.i("DatabaseUpgrade", "table created: "+table.getName());
}
else
{
Table currentDatabaseTable = Table.fromCursor(table.getName(), cursor);
for (String sql : Table.upgradeTable(currentDatabaseTable, table))
{
database.execSQL(sql);
Log.i("DatabaseUpgrade", "table altered. Query: "+sql);
}
}
}
public void upgradeDatabase()
{
SQLiteDatabase database = getWritableDatabase();
upgradeDatabase(database);
database.close();
}
public void upgradeDatabase(SQLiteDatabase database)
{
for (Class<?> c : this.classes)
{
upgradeTable(database, new Table(c));
}
}
/**
* Add classes to the collection of tracked classes.
* You should call this before onCreate to ensure that all tables are automatically created for your classes.
*/
public void trackClasses(Collection<Class<?>> classes)
{
this.classes.addAll(classes);
}
/**
* Add single class to be automatically added to database in onCreate.
* @param trackedClass
*/
public void trackClass(Class<?> trackedClass)
{
this.classes.add(trackedClass);
}
/**
* Add classes to the collection of tracked classes.
* You should call this before onCreate to ensure that all tables are automatically created for your classes.
*/
public void trackClasses(Class<?>[] classes)
{
for (Class<?> c : classes)
trackClass(c);
}
@Override
public void onCreate(SQLiteDatabase db)
{
for (Class<?> c : classes)
createTable(db, c, true);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
upgradeDatabase(db);
}
/**
@@ -1,10 +1,8 @@
package com.michaldabski.msqlite.models;
import java.io.NotSerializableException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Locale;
import android.database.Cursor;
import android.util.Log;
import com.michaldabski.msqlite.Annotations.ColumnName;
@@ -30,25 +28,48 @@
dataType,
// table.field
uniqueName;
protected final Class<?> fieldClass;
private final int fieldType;
public Column(Field field)
public static Column fromCursor(Cursor cursor, Table table)
{
final int FIELD_NAME = 1,
FIELD_TYPE = 2,
FIELD_NOT_NULL = 3,
FIELD_DEF_VALUE = 4,
FIELD_PK = 5;
String name = cursor.getString(FIELD_NAME);
Column column = new Column(null, cursor.getInt(FIELD_NOT_NULL)==1, cursor.getInt(FIELD_PK)==1, name,
cursor.getString(FIELD_TYPE), table.getName()+"."+name, DataTypes.TYPE_NA);
return column;
}
private Column(Field field, boolean nOT_NULL, boolean pRIMARY_KEY,
String name, String dataType, String uniqueName,
int fieldType)
{
this.field = field;
NOT_NULL = nOT_NULL;
PRIMARY_KEY = pRIMARY_KEY;
this.name = name;
this.dataType = dataType;
this.uniqueName = uniqueName;
this.fieldType = fieldType;
}
public Column(Field field, Table table)
{
this.field =field;
if (field.isAnnotationPresent(ColumnName.class)) this.name = field.getAnnotation(ColumnName.class).value();
else this.name = field.getName();
this.fieldClass = field.getType();
this.uniqueName = String.format("%s.%s", field.getDeclaringClass().getSimpleName(), name);
this.uniqueName = String.format("%s.%s", table.getName(), name);
fieldType = DataTypes.getFieldType(fieldClass);
fieldType = DataTypes.getFieldType(field.getType());
if (fieldType == DataTypes.TYPE_OTHER)
{
Log.w("MSQLite", fieldClass.getSimpleName()+" is not supported as a table field yet. Consider making this field transient.");
Log.w("MSQLite", field.getType().getSimpleName()+" is not supported as a table field yet. Consider making this field transient.");
dataType = null;
return;
}
@@ -103,7 +124,9 @@ public int hashCode()
@Override
public boolean equals(Object obj)
{
return uniqueName.equals(obj);
if (obj instanceof Column)
return uniqueName.equals(((Column) obj).uniqueName);
else return super.equals(obj);
}
public Object getValue(Object object) throws IllegalArgumentException, NoSuchFieldException
@@ -169,6 +192,11 @@ public int getFieldType()
return fieldType;
}
public boolean isPRIMARY_KEY()
{
return PRIMARY_KEY;
}
public void setValueFromString(Object object, String value) throws IllegalArgumentException
{
try
@@ -29,6 +29,59 @@
protected final List<Column> columns;
protected final List<Column> primaryKeys;
/**
* Create table instance from cursor
* @param cursor PRAGMA table_info(TABLE_NAME);
* @return table model based on data from the cursor
*/
public static Table fromCursor(String tableName, Cursor cursor)
{
Table result = new Table(tableName, new ArrayList<Column>(cursor.getCount()));
while (cursor.moveToNext())
{
Column column = Column.fromCursor(cursor, result);
result.columns.add(column);
if (column.isPRIMARY_KEY())
result.primaryKeys.add(column);
}
return result;
}
/**
* Create upgrade statements according to sqlite rules:
* http://www.sqlite.org/lang_altertable.html
* only new columns are added.
* @return alter statements to alter upgradeFrom table into this table
*/
public List<String> upgradeTable(Table upgradeFrom)
{
List<String> result = new ArrayList<String>();
// add new columns
for (Column column : columns)
{
if (upgradeFrom.columns.contains(column) == false)
{
StringBuilder resultBuilder = new StringBuilder("Alter table `").append(this.name)
.append("` ADD COLUMN ").append(column.getBuilder()).append(';');
result.add(resultBuilder.toString());
}
}
return result;
}
public static List<String> upgradeTable(Table currentTable, Table newTable)
{
return newTable.upgradeTable(currentTable);
}
private Table(String name, List<Column> columns)
{
this.name = name;
this.columns = columns;
this.primaryKeys = new ArrayList<Column>(1);
}
/**
* Create Table from java class definition
*
@@ -57,7 +110,7 @@ public Table(Class<?> type)
for (Field field : fields)
{
if ((field.getModifiers() & (Modifier.TRANSIENT | Modifier.STATIC | Modifier.FINAL)) > 0) continue;
Column column = new Column(field);
Column column = new Column(field, this);
if (column.getDataType() == null) continue;
columns.add(column);
if (column.PRIMARY_KEY) primaryKeys.add(column);
@@ -11,11 +11,16 @@
{
private boolean
IF_NOT_EXISTS = false;
public CreateTable(Class<?> type)
{
super(type);
}
public CreateTable(Table table)
{
super(table);
}
public CreateTable setIF_NOT_EXIST(boolean iF_NOT_EXIST)
{
@@ -5,17 +5,23 @@
public abstract class QueryBuilder
{
protected Class<?> type;
protected Table table;
protected String condition = "1";
@Deprecated
public QueryBuilder(Class<?> type)
{
this.type = type;
this.table = new Table(type);
}
public QueryBuilder(Table table)
{
this.table = table;
}
public Table getTable()
{
return new Table(type);
return table;
}
// public abstract <T> Result<T> execute(Class<T> type);

0 comments on commit 313e1f3

Please sign in to comment.