Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Address issue #10:
Browse files Browse the repository at this point in the history
* Give more meaningful exceptions from Entity#load()
* Remove default type mapping (it doesn't work with the new load API)
* Add mapping for java.util.Date.

Thanks to rothschild86 for this bug report.
  • Loading branch information
roscopeco committed Jul 2, 2013
1 parent 0892d5e commit 7cb185a
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 13 deletions.
53 changes: 53 additions & 0 deletions src/com/roscopeco/ormdroid/DateTypeMapping.java
@@ -0,0 +1,53 @@
/*
* Copyright 2012 Ross Bamford
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.roscopeco.ormdroid;

import java.util.Date;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

/*
* Map java.util.Date to the database.
*
* This implementation just stashes the number of seconds
* since the epoch in a BIGINT.
*/
public class DateTypeMapping implements TypeMapping {
private Class<?> mJavaType;
private String mSqlType;

public DateTypeMapping() {
mJavaType = Date.class;
mSqlType = "BIGINT";
}

public Class<?> javaType() {
return mJavaType;
}

public String sqlType(Class<?> concreteType) {
return mSqlType;
}

public String encodeValue(SQLiteDatabase db, Object value) {
return "\"" + ((Date)value).getTime() + "\"";
}

public Object decodeValue(SQLiteDatabase db, Class<?> expectedType, Cursor c, int columnIndex) {
return new Date(c.getInt(columnIndex));
}
}
17 changes: 14 additions & 3 deletions src/com/roscopeco/ormdroid/Entity.java
Expand Up @@ -174,7 +174,6 @@ static final class EntityMapping {
static EntityMapping build(Class<? extends Entity> clz) {
EntityMapping mapping = new EntityMapping();
mapping.mMappedClass = clz;

Table table = clz.getAnnotation(Table.class);
if (table != null) {
mapping.mTableName = table.name();
Expand Down Expand Up @@ -207,6 +206,15 @@ static EntityMapping build(Class<? extends Entity> clz) {
(!Modifier.isPrivate(modifiers) || force) &&
!seenFields.contains(f.getName()) &&
!inverse) {

// Check we can map this type - if not, let's fail fast.
// This will save us wierd exceptions somewhere down the line...
if (TypeMapper.getMapping(f.getType()) == null) {
throw new TypeMappingException("Model " +
clz.getName() +
" has unmappable field: " + f);
}

Column col = f.getAnnotation(Column.class);
String name;

Expand Down Expand Up @@ -466,12 +474,15 @@ <T extends Entity> T load(SQLiteDatabase db, Cursor c) {
}

return model;
} catch (Exception e) {
} catch (InstantiationException e) {
throw new ORMDroidException(
"Failed to instantiate model class - does it have a public null constructor?",
e);
} catch (IllegalAccessException e) {
throw new ORMDroidException(
"Access denied. Is your model's constructor non-public?",
e);
}

}

/*
Expand Down
17 changes: 7 additions & 10 deletions src/com/roscopeco/ormdroid/TypeMapper.java
Expand Up @@ -22,8 +22,9 @@
*
* <p>By default, ORMDroid provides a mapping for all primitive types
* and Entity classes. All other types are mapped by the <em>default
* mapping</em>, which simply stores their <code>toString</code> results
* in a <code>VARCHAR</code> column.</p>
* mapping</em> (if configured with {@link #setDefaultMapping(TypeMapping)}).
* By default, there is no default mapping - attempting to use a model class
* with a field of an unmapped type will throw an exception.</p>
*
* <p>Custom types may be mapped by registering an instance of
* {@link TypeMapping} via the {@link #mapType(TypeMapping) mapType} method.
Expand All @@ -41,7 +42,7 @@
*/
public final class TypeMapper {
private static final MappingList TYPEMAPS = new MappingList();
private static TypeMapping mDefaultMapping = new StringTypeMapping(Object.class, "VARCHAR");
private static TypeMapping mDefaultMapping = null;

public static String sqlType(Class<?> type) {
return getMapping(type).sqlType(type);
Expand All @@ -51,19 +52,14 @@ public static String sqlType(Class<?> type) {
* Obtain the configured mapping the the specified Java type.
*
* @param type the Java type.
* @return the configured mapping.
* @return the configured mapping, or <code>null</code> if none.
*/
public static TypeMapping getMapping(Class<?> type) {
TypeMapping r = TYPEMAPS.findMapping(type);
if (r != null) {
return r;
} else {
TypeMapping def = mDefaultMapping;
if (def != null) {
return def;
} else {
throw new TypeMappingException("No mapping found for type `" + type + "'");
}
return mDefaultMapping;
}
}

Expand Down Expand Up @@ -115,6 +111,7 @@ public static void setDefaultMapping(TypeMapping mapping) {
mapType(new NumericTypeMapping(boolean.class, "TINYINT"));
mapType(new NumericTypeMapping(Long.class, "BIGINT"));
mapType(new NumericTypeMapping(long.class, "BIGINT"));
mapType(new DateTypeMapping());
mapType(new EntityTypeMapping());
mapType(new NumericTypeMapping(Integer.class, "INTEGER"));
mapType(new NumericTypeMapping(int.class, "INTEGER"));
Expand Down

0 comments on commit 7cb185a

Please sign in to comment.