Skip to content

Commit 834914c

Browse files
committed
Merge pull request #230 from sabadow/master
Fix the issue #106 (#106)
2 parents 12c6937 + c97998d commit 834914c

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed

src/com/activeandroid/Model.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import com.activeandroid.util.ReflectionUtils;
2929

3030
import java.lang.reflect.Field;
31+
import java.util.ArrayList;
32+
import java.util.Arrays;
3133
import java.util.List;
3234

3335
@SuppressWarnings("unchecked")
@@ -176,10 +178,15 @@ public static <T extends Model> T load(Class<T> type, long id) {
176178
// Model population
177179

178180
public final void loadFromCursor(Cursor cursor) {
181+
/**
182+
* Obtain the columns ordered to fix issue #106 (https://github.com/pardom/ActiveAndroid/issues/106)
183+
* when the cursor have multiple columns with same name obtained from join tables.
184+
*/
185+
List<String> columnsOrdered = new ArrayList<String>(Arrays.asList(cursor.getColumnNames()));
179186
for (Field field : mTableInfo.getFields()) {
180187
final String fieldName = mTableInfo.getColumnName(field);
181188
Class<?> fieldType = field.getType();
182-
final int columnIndex = cursor.getColumnIndex(fieldName);
189+
final int columnIndex = columnsOrdered.indexOf(fieldName);
183190

184191
if (columnIndex < 0) {
185192
continue;

src/com/activeandroid/util/SQLiteUtils.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@
2727
import com.activeandroid.annotation.Column.ConflictAction;
2828
import com.activeandroid.serializer.TypeSerializer;
2929

30+
import java.lang.Long;
31+
import java.lang.String;
3032
import java.lang.reflect.Constructor;
3133
import java.lang.reflect.Field;
34+
import java.util.Arrays;
3235
import java.util.ArrayList;
3336
import java.util.HashMap;
3437
import java.util.List;
@@ -327,8 +330,13 @@ public static <T extends Model> List<T> processCursor(Class<? extends Model> typ
327330
Constructor<?> entityConstructor = type.getConstructor();
328331

329332
if (cursor.moveToFirst()) {
333+
/**
334+
* Obtain the columns ordered to fix issue #106 (https://github.com/pardom/ActiveAndroid/issues/106)
335+
* when the cursor have multiple columns with same name obtained from join tables.
336+
*/
337+
List<String> columnsOrdered = new ArrayList<String>(Arrays.asList(cursor.getColumnNames()));
330338
do {
331-
Model entity = Cache.getEntity(type, cursor.getLong(cursor.getColumnIndex(idName)));
339+
Model entity = Cache.getEntity(type, cursor.getLong(columnsOrdered.indexOf(idName)));
332340
if (entity == null) {
333341
entity = (T) entityConstructor.newInstance();
334342
}

tests/src/com/activeandroid/test/ModelTest.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,15 @@
1919
import com.activeandroid.Cache;
2020
import com.activeandroid.Model;
2121
import com.activeandroid.TableInfo;
22+
import com.activeandroid.annotation.Column;
2223
import com.activeandroid.annotation.Table;
2324
import com.activeandroid.query.Select;
2425

2526
import java.lang.reflect.Field;
27+
import java.util.ArrayList;
28+
import java.util.Date;
2629
import java.util.HashSet;
30+
import java.util.List;
2731
import java.util.Set;
2832

2933
/**
@@ -167,11 +171,97 @@ public void testBooleanColumnType() {
167171
assertNull( new Select().from(MockModel.class).where("booleanField = ?", 1).executeSingle() );
168172

169173
assertNull( new Select().from(MockModel.class).where("booleanField = ?", true).executeSingle() );
174+
}
175+
176+
/**
177+
* Test to check the join of two (or more) tables with some fields in common when not use a projection on select.
178+
* Test the issue #106 (https://github.com/pardom/ActiveAndroid/issues/106)
179+
*/
180+
public void testJoinWithSameNames(){
181+
//create a parent entity and store
182+
ParentJoinMockModel parent = new ParentJoinMockModel();
183+
parent.booleanField = true;
184+
parent.dateField = new Date();
185+
parent.doubleField = 2.0;
186+
parent.intField = 1;
187+
parent.save();
188+
189+
//the values to assign to child
190+
Date dateValue = new Date();
191+
double doubleValue = 30.0;
192+
int intValue = 3;
193+
194+
//create two child entities, relate with parent and save
195+
ChildMockModel child1 = new ChildMockModel();
196+
child1.booleanField = false;
197+
child1.dateField = dateValue;
198+
child1.doubleField = doubleValue;
199+
child1.intField = intValue;
200+
child1.parent = parent;
201+
child1.save();
202+
203+
ChildMockModel child2 = new ChildMockModel();
204+
child2.booleanField = false;
205+
child2.dateField = dateValue;
206+
child2.doubleField = doubleValue;
207+
child2.intField = intValue;
208+
child2.parent = parent;
209+
child2.save();
210+
211+
//Store the ids assigned to child entities when persists
212+
List<Long> ids = new ArrayList<Long>();
213+
ids.add(child1.getId());
214+
ids.add(child2.getId());
215+
216+
//make the query with a join
217+
List<ChildMockModel> result = new Select().from(ChildMockModel.class).
218+
join(ParentJoinMockModel.class).on("ParentJoinMockModel.Id = ChildMockModel.parent").execute();
219+
220+
//check result
221+
assertNotNull(result);
222+
assertEquals(result.size(), 2);
223+
for(ChildMockModel currentModel : result){
224+
assertFalse(currentModel.booleanField);
225+
assertEquals(currentModel.intField, intValue);
226+
assertEquals(currentModel.doubleField, doubleValue);
227+
assertTrue(ids.contains(currentModel.getId()));
228+
}
229+
170230
}
171231

172232
/**
173233
* Mock model as we need 2 different model classes.
174234
*/
175235
@Table(name = "AnotherMockTable")
176236
public static class AnotherMockModel extends Model {}
237+
238+
/**
239+
* Mock model to test joins with same names.
240+
* It's a copy from MockModel.
241+
*/
242+
@Table(name = "ParentJoinMockModel")
243+
public static class ParentJoinMockModel extends Model {
244+
@Column
245+
public Date dateField;
246+
247+
@Column
248+
public double doubleField;
249+
250+
@Column
251+
public int intField;
252+
253+
@Column
254+
public boolean booleanField;
255+
}
256+
257+
/**
258+
* Mock model to test joins with same names.
259+
* Extends from ParentJoinMockModel to have the same columns.
260+
* Have a relationship with ParentJoinMockModel to make te join query.
261+
*/
262+
@Table(name = "ChildMockModel")
263+
public static class ChildMockModel extends ParentJoinMockModel {
264+
@Column
265+
ParentJoinMockModel parent;
266+
}
177267
}

0 commit comments

Comments
 (0)