// Path: onam/src/main/java/com/basilgregory/onam/android/DbUtil.java
// static String getColumnName(Field field){
//     return getColumnName(getMethod("get", field));
// }
// 
// Path: onam/src/main/java/com/basilgregory/onam/android/DbUtil.java
// static String getMappingForeignColumnNameClass(Class aClass){
//     return aClass.getSimpleName().toLowerCase()+"_id";
// }


import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.basilgregory.onam.annotations.AfterCreate;
import com.basilgregory.onam.annotations.AfterUpdate;
import com.basilgregory.onam.annotations.BeforeCreate;
import com.basilgregory.onam.annotations.BeforeUpdate;
import com.basilgregory.onam.annotations.ManyToMany;
import com.basilgregory.onam.annotations.OneToMany;
import com.basilgregory.onam.annotations.Table;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.basilgregory.onam.android.DbUtil.getColumnName;
import static com.basilgregory.onam.android.DbUtil.getMappingForeignColumnNameClass;

    List<Entity> findAllWithOrderBy(Class<Entity> cls, String whereClause, String orderByColumn,boolean descending, Integer startIndex, Integer pageSize) {
        return convertToEntityAndFetchFirstDegreeRelatedEntity(getReadableDatabase().rawQuery
                        (QueryBuilder.findAll(cls, whereClause,orderByColumn,descending, startIndex, pageSize), null)
                ,cls);
    }

    // Private methods

    private List<Entity> findOneToManyRelatedEntities(Entity entity, Object holderClass
            ,OneToMany oneToMany,Method method ) {
        Class collectionType = holderClass.getClass().getSuperclass();
        List<Entity> entities = findByProperty(collectionType,
                DbUtil.getReferencedColumnName(oneToMany,entity.getClass()),entity.getId(),null,null);
        DbUtil.invokeSetter(entity,DbUtil.getSetterMethod(method),entities);
        return entities;

    }

    /**
     * Mapping table name has to be provided by the user.
     * Foreignkey column names will be auto generated using #{getMappingForeignColumnNameClass}.
     * @param entity
     * @param holderClass
     * @param method
     * @return
     */
    private List<Entity> findManyToManyRelatedEntities(ManyToMany manyToMany,Entity entity, Object holderClass
            , Method method ) {
        Cursor cursor =  findByProperty(manyToMany.tableName(),
// Path: onam/src/main/java/com/basilgregory/onam/android/DbUtil.java
// static String getColumnName(Field field){
//     return getColumnName(getMethod("get", field));
// }
// 
// Path: onam/src/main/java/com/basilgregory/onam/android/DbUtil.java
// static String getMappingForeignColumnNameClass(Class aClass){
//     return aClass.getSimpleName().toLowerCase()+"_id";
// }


// Path: onam/src/main/java/com/basilgregory/onam/android/DBExecutor.java
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.basilgregory.onam.annotations.AfterCreate;
import com.basilgregory.onam.annotations.AfterUpdate;
import com.basilgregory.onam.annotations.BeforeCreate;
import com.basilgregory.onam.annotations.BeforeUpdate;
import com.basilgregory.onam.annotations.ManyToMany;
import com.basilgregory.onam.annotations.OneToMany;
import com.basilgregory.onam.annotations.Table;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.basilgregory.onam.android.DbUtil.getColumnName;
import static com.basilgregory.onam.android.DbUtil.getMappingForeignColumnNameClass;


    List<Entity> findAllWithOrderBy(Class<Entity> cls, String whereClause, String orderByColumn,boolean descending, Integer startIndex, Integer pageSize) {
        return convertToEntityAndFetchFirstDegreeRelatedEntity(getReadableDatabase().rawQuery
                        (QueryBuilder.findAll(cls, whereClause,orderByColumn,descending, startIndex, pageSize), null)
                ,cls);
    }

    // Private methods

    private List<Entity> findOneToManyRelatedEntities(Entity entity, Object holderClass
            ,OneToMany oneToMany,Method method ) {
        Class collectionType = holderClass.getClass().getSuperclass();
        List<Entity> entities = findByProperty(collectionType,
                DbUtil.getReferencedColumnName(oneToMany,entity.getClass()),entity.getId(),null,null);
        DbUtil.invokeSetter(entity,DbUtil.getSetterMethod(method),entities);
        return entities;

    }

    /**
     * Mapping table name has to be provided by the user.
     * Foreignkey column names will be auto generated using #{getMappingForeignColumnNameClass}.
     * @param entity
     * @param holderClass
     * @param method
     * @return
     */
    private List<Entity> findManyToManyRelatedEntities(ManyToMany manyToMany,Entity entity, Object holderClass
            , Method method ) {
        Cursor cursor =  findByProperty(manyToMany.tableName(),
                getMappingForeignColumnNameClass(entity.getClass()),entity.getId(),null,null);