Skip to content

Commit

Permalink
introduced Table annotation to handle custom table naming and removin…
Browse files Browse the repository at this point in the history
…g the SugarRecord dependency
  • Loading branch information
Satya Narayan committed Jul 16, 2014
1 parent 25588f3 commit 36649d5
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 234 deletions.
14 changes: 8 additions & 6 deletions example/src/com/example/Note.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.orm.SugarRecord;
import com.orm.dsl.Column;
import com.orm.dsl.Table;

This comment has been minimized.

Copy link
@jhonvidal

jhonvidal Sep 8, 2014

is not wrapped around the sugar-1.3.jar library, I want to use it please help


@Table(name = "Note")
public class Note extends SugarRecord<Note>{

@Column(name = "noteId", unique = true, notNull = true)
Expand Down Expand Up @@ -42,20 +44,20 @@ public String getTitle() {
return title;
}

public String getDescription() {
return description;
public void setTitle(String title) {
this.title = title;
}

public Tag getTag() {
return tag;
public String getDescription() {
return description;
}

public void setDescription(String description){
this.description = description;
}

public void setTitle(String title) {
this.title = title;
public Tag getTag() {
return tag;
}

@Override
Expand Down
11 changes: 4 additions & 7 deletions example/src/com/example/SugarActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@

import android.app.Activity;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import com.orm.Database;
import com.orm.SugarApp;
import com.orm.SugarRecord;

public class SugarActivity extends Activity
{
Expand All @@ -16,9 +13,9 @@ public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Note.deleteAll(Note.class);
TextNote.deleteAll(TextNote.class);
Tag.deleteAll(Tag.class);
SugarRecord.deleteAll(Note.class);
SugarRecord.deleteAll(TextNote.class);
SugarRecord.deleteAll(Tag.class);
initDb();
Intent intent = new Intent(this, NoteListActivity.class);
startActivity(intent);
Expand Down
69 changes: 39 additions & 30 deletions library/src/com/orm/StringUtil.java
Original file line number Diff line number Diff line change
@@ -1,50 +1,59 @@
package com.orm;

import com.orm.dsl.Column;
import com.orm.dsl.Table;

import java.lang.reflect.Field;

public class StringUtil {
public static String toSQLNameDefault(String javaNotation) {
if(javaNotation.equalsIgnoreCase("_id"))
return "_id";

StringBuilder sb = new StringBuilder();
char[] buf = javaNotation.toCharArray();

for (int i = 0; i < buf.length; i++) {
char prevChar = (i > 0) ? buf[i - 1] : 0;
char c = buf[i];
char nextChar = (i < buf.length - 1) ? buf[i + 1] : 0;
boolean isFirstChar = (i == 0);

if (isFirstChar || Character.isLowerCase(c) || Character.isDigit(c)) {
sb.append(Character.toUpperCase(c));
} else if (Character.isUpperCase(c)) {
if (Character.isLetterOrDigit(prevChar)) {
if (Character.isLowerCase(prevChar)) {
sb.append('_').append(Character.toUpperCase(c));
} else if (nextChar > 0 && Character.isLowerCase(nextChar)) {
sb.append('_').append(Character.toUpperCase(c));
} else {
sb.append(c);
}
}
else {
sb.append(c);
}
if (javaNotation.equalsIgnoreCase("_id"))
return "_id";

StringBuilder sb = new StringBuilder();
char[] buf = javaNotation.toCharArray();

for (int i = 0; i < buf.length; i++) {
char prevChar = (i > 0) ? buf[i - 1] : 0;
char c = buf[i];
char nextChar = (i < buf.length - 1) ? buf[i + 1] : 0;
boolean isFirstChar = (i == 0);

if (isFirstChar || Character.isLowerCase(c) || Character.isDigit(c)) {
sb.append(Character.toUpperCase(c));
} else if (Character.isUpperCase(c)) {
if (Character.isLetterOrDigit(prevChar)) {
if (Character.isLowerCase(prevChar)) {
sb.append('_').append(Character.toUpperCase(c));
} else if (nextChar > 0 && Character.isLowerCase(nextChar)) {
sb.append('_').append(Character.toUpperCase(c));
} else {
sb.append(c);
}
} else {
sb.append(c);
}
}
}

return sb.toString();
return sb.toString();
}

public static String toSQLName(Field field){
if(field.isAnnotationPresent(Column.class)){
public static String toSQLName(Field field) {
if (field.isAnnotationPresent(Column.class)) {
Column annotation = field.getAnnotation(Column.class);
return annotation.name();
}

return toSQLNameDefault(field.getName());
}

public static String toSQLName(Class<?> table) {

if (table.isAnnotationPresent(Table.class)) {
Table annotation = table.getAnnotation(Table.class);
return annotation.name();
}
return StringUtil.toSQLNameDefault(table.getSimpleName());
}
}
137 changes: 72 additions & 65 deletions library/src/com/orm/SugarDb.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,22 @@
package com.orm;

import static com.orm.SugarConfig.getDatabaseVersion;
import static com.orm.SugarConfig.getDebugEnabled;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import android.content.Context;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.orm.dsl.*;
import dalvik.system.DexFile;

import com.orm.dsl.Column;
import com.orm.dsl.NotNull;
import com.orm.dsl.Unique;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.*;

import dalvik.system.DexFile;
import static com.orm.SugarConfig.getDatabaseVersion;
import static com.orm.SugarConfig.getDebugEnabled;

public class SugarDb extends SQLiteOpenHelper {
private Context context;
Expand All @@ -40,16 +27,45 @@ public SugarDb(Context context) {

}

private <T extends SugarRecord<?>> List<T> getDomainClasses(Context context) {
List<T> domainClasses = new ArrayList<T>();
public static List<Field> getTableFields(Class table) {
List<Field> fieldList = SugarConfig.getFields(table);
if (fieldList != null) return fieldList;

Log.d("Sugar", "Fetching properties");
List<Field> typeFields = new ArrayList<Field>();

getAllFields(typeFields, table);

List<Field> toStore = new ArrayList<Field>();
for (Field field : typeFields) {
if (!field.isAnnotationPresent(Ignore.class) && !Modifier.isStatic(field.getModifiers()) && !Modifier.isTransient(field.getModifiers())) {
toStore.add(field);
}
}

SugarConfig.setFields(table, toStore);
return toStore;
}

private static List<Field> getAllFields(List<Field> fields, Class<?> type) {
Collections.addAll(fields, type.getDeclaredFields());

if (type.getSuperclass() != null) {
fields = getAllFields(fields, type.getSuperclass());
}

return fields;
}

private List<Class> getDomainClasses(Context context) {
List<Class> domainClasses = new ArrayList<Class>();
try {
for (String className : getAllClasses(context)) {
if (className.startsWith(SugarConfig.getDomainPackageName(context))) {
T domainClass = getDomainClass(className, context);
Class domainClass = getDomainClass(className, context);
if (domainClass != null) domainClasses.add(domainClass);
}
}

} catch (IOException e) {
Log.e("Sugar", e.getMessage());
} catch (PackageManager.NameNotFoundException e) {
Expand All @@ -59,38 +75,26 @@ private <T extends SugarRecord<?>> List<T> getDomainClasses(Context context) {
return domainClasses;
}

@SuppressWarnings("unchecked")
private <T extends SugarRecord<?>> T getDomainClass(String className, Context context) {
private Class getDomainClass(String className, Context context) {
Class<?> discoveredClass = null;
try {
discoveredClass = Class.forName(className, true, context.getClass().getClassLoader());
} catch (ClassNotFoundException e) {
Log.e("Sugar", e.getMessage());
}

if ((discoveredClass == null) ||
(!SugarRecord.class.isAssignableFrom(discoveredClass)) ||
SugarRecord.class.equals(discoveredClass) ||
Modifier.isAbstract(discoveredClass.getModifiers())) {
return null;
} else {
try {
Log.i("Sugar", "domain class : " + discoveredClass.getSimpleName());
return (T) discoveredClass.getDeclaredConstructor().newInstance();

} catch (InstantiationException e) {
Log.e("Sugar", e.getMessage());
} catch (IllegalAccessException e) {
Log.e("Sugar", e.getMessage());
} catch (NoSuchMethodException e) {
Log.e("Sugar", e.getMessage());
} catch (InvocationTargetException e) {
Log.e("Sugar", e.getMessage());
}
}
if ((discoveredClass != null) &&
((SugarRecord.class.isAssignableFrom(discoveredClass) &&
!SugarRecord.class.equals(discoveredClass)) ||
discoveredClass.isAnnotationPresent(Table.class)) &&
!Modifier.isAbstract(discoveredClass.getModifiers())) {

return null;
Log.i("Sugar", "domain class : " + discoveredClass.getSimpleName());
return discoveredClass;

} else {
return null;
}
}

private List<String> getAllClasses(Context context) throws PackageManager.NameNotFoundException, IOException {
Expand Down Expand Up @@ -119,7 +123,7 @@ private List<String> getAllClasses(Context context) throws PackageManager.NameNo
}
return classNames;
}

private void populateFiles(File path, List<String> fileNames, String parent) {
if (path.isDirectory()) {
for (File newPath : path.listFiles()) {
Expand Down Expand Up @@ -152,17 +156,20 @@ public void onCreate(SQLiteDatabase sqLiteDatabase) {
createDatabase(sqLiteDatabase);
}

private <T extends SugarRecord<?>> void createDatabase(SQLiteDatabase sqLiteDatabase) {
List<T> domainClasses = getDomainClasses(context);
for (T domain : domainClasses) {
private void createDatabase(SQLiteDatabase sqLiteDatabase) {
List<Class> domainClasses = getDomainClasses(context);
for (Class domain : domainClasses) {
createTable(domain, sqLiteDatabase);
}
}

private <T extends SugarRecord<?>> void createTable(T table, SQLiteDatabase sqLiteDatabase) {
private <T extends SugarRecord<?>> void createTable(Class<?> table, SQLiteDatabase sqLiteDatabase) {
Log.i("Sugar", "create table");
List<Field> fields = table.getTableFields();
StringBuilder sb = new StringBuilder("CREATE TABLE ").append(table.getSqlName()).append(
List<Field> fields = getTableFields(table);

String tableName = StringUtil.toSQLName(table);

StringBuilder sb = new StringBuilder("CREATE TABLE ").append(tableName).append(
" ( ID INTEGER PRIMARY KEY AUTOINCREMENT ");

for (Field column : fields) {
Expand Down Expand Up @@ -211,7 +218,7 @@ private <T extends SugarRecord<?>> void createTable(T table, SQLiteDatabase sqLi
}
sb.append(" ) ");

Log.i("Sugar", "creating table " + table.getSqlName());
Log.i("Sugar", "creating table " + tableName);

if (!"".equals(sb.toString()))
sqLiteDatabase.execSQL(sb.toString());
Expand All @@ -232,22 +239,22 @@ public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVers
/**
* Create the tables that do not exist.
*/
private <T extends SugarRecord<?>> void doUpgrade(SQLiteDatabase sqLiteDatabase) {
List<T> domainClasses = getDomainClasses(context);
for (T domain : domainClasses) {
private void doUpgrade(SQLiteDatabase sqLiteDatabase) {
List<Class> domainClasses = getDomainClasses(context);
for (Class domain : domainClasses) {
try {// we try to do a select, if fails then (?) there isn't the table
sqLiteDatabase.query(domain.tableName, null, null, null, null, null, null);
sqLiteDatabase.query(StringUtil.toSQLName(domain), null, null, null, null, null, null);
} catch (SQLiteException e) {
Log.i("Sugar", String.format("creating table on update (error was '%s')", e.getMessage()));
createTable(domain, sqLiteDatabase);
}
}
}

private <T extends SugarRecord<?>> void deleteTables(SQLiteDatabase sqLiteDatabase) {
List<T> tables = getDomainClasses(this.context);
for (T table : tables) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + table.getSqlName());
private void deleteTables(SQLiteDatabase sqLiteDatabase) {
List<Class> tables = getDomainClasses(this.context);
for (Class table : tables) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + StringUtil.toSQLName(table));
}
}

Expand Down
Loading

0 comments on commit 36649d5

Please sign in to comment.