Sirat, create your Pojo and We generate the query
I’m to lazy to create a pojo and a query to provide in contentprovider. So after thinking i’m have decide to cut this and create a tools to help that. So i’m created Sirat.
Sirat (https://github.com/linggom/sirat/) is using annotation like in hibernate (http://hibernate.org/) to set some attribute in java. Actually this is what sirat do can convert from this :
When we called
Sirat.generateQuery(Dog.class))
It will convert this class :
class Dog{
@PRIMARY_KEY private String name;
@NOT_NULL private String type;
private long birthDate;
@UNIQUE private int uuid;
@Ignore private String birthPlace;
}
Into this class :
CREATE TABLE 'Dog' (
'type' TEXT NOT NULL ,
'name' TEXT,
'uuid' INTEGER,
'birthDate' LONG,
PRIMARY KEY ('name'),
UNIQUE ('uuid')
)
So how it works actually ?
It’s very simple first I get attribute from the class, using Dog.class.getDeclaredFields it will return Field[].
After receiving array of fields I iterate all of the array to get the data type (objectFile.getType().getName()) and get name of the field(f.getType().getName()).
But there is another problem, about the supported data type because in java you have primitive data type(int, long, char) and Modern data type (Integer, Long, Character).
So I decide to use mapping the data type to sqllite data type.
private static final Map<String, String> mMapDataTypeWithField = new HashMap<String, String>() {
public final Map<String, String> initMapping() {
Map<String, String> map = new HashMap<String, String>();
map.put(String.class.getName(), DataType.TEXT.toString());
map.put(Integer.class.getName(), DataType.INTEGER.toString());
map.put("int", DataType.INTEGER.toString());
map.put(Long.class.getName(), DataType.LONG.toString());
map.put("long", DataType.LONG.toString());
map.put(Double.class.getName(), DataType.DOUBLE.toString());
map.put("double", DataType.DOUBLE.toString());
map.put(Float.class.getName(), DataType.FLOAT.toString());
map.put("float", DataType.FLOAT.toString());
map.put(Boolean.class.getName(), DataType.BOOLEAN.toString());
map.put("boolean", DataType.BOOLEAN.toString());
map.put(Byte.class.getName(), DataType.BYTE.toString());
map.put("byte", DataType.BYTE.toString());
map.put(Short.class.getName(), DataType.SHORT.toString());
map.put("short", DataType.SHORT.toString());
map.put(Character.class.getName(), DataType.CHAR.toString());
map.put("char", DataType.CHAR.toString());
return map;
}
}.initMapping()
Okay but how I translate the annotation ? This is what I do :
Annotation[] annotations = f.getAnnotations();
for (Annotation an : annotations) {
String annotation = an.annotationType().getSimpleName();
if (annotation.equals(ROW_ID.class.getSimpleName())) {
if (ai == false) {
int idx = -1;
if ((idx = unique_index.indexOf(fieldName)) > -1) {
unique_index.remove(idx);
}
if ((idx = primary_key.indexOf(fieldName)) > -1) {
primary_key.remove(idx);
}
newField = ((field_query.equals("") || field_query == null) ? "" : COMMA) + ROW_ID_ATTRIBUTE;
ai = true;
}
break;
} else if (annotation.equals(PRIMARY_KEY.class.getSimpleName())) {
primary_key.add(fieldName);
} else if (annotation.equals(NOT_NULL.class.getSimpleName())) {
newField += NOT_NULL_ATTRIBUTE;
} else if (annotation.equals(UNIQUE.class.getSimpleName())) {
unique_index.add(fieldName);
} else if (annotation.equals(PRIMARY_KEY.class.getSimpleName())) {
newField += NOT_NULL_ATTRIBUTE;
primary_key.add(fieldName);
}
else if (annotation.equals(Ignore.class.getSimpleName())){
newField = "";
break;
}
}
I’m iterating the over the annotation and merge it with current processed field. But once again SqlLite have a new speciality about the auto increment.
To have an auto increment field you must put the auto increment in ‘rowid’ field with primary_key. And what if there is other fields want to be declared as primary_key?
I found the solution, I decide to make them unique but if the data is unique is not guarantee the data is not null.
So when the field is declared as primary_key and if there is rowid field, make the field is not null and make them unique as alternate of the primary_key. After that i’m join the generated field into a sqllite valid query. But Sirat is still beta, i recommend you to use it when i’m finish doing the unit test. I’m published it because if there is some on who are interesting to develop Sirat based on their need and the pojo is simple by using primitive data type or modern data type. Next week i want to implement the OneToMany and ManyToOne that implemented in Hibernate and implement it in sirat.
If you want to explore it you can see it at : https://github.com/linggom/sirat/