package com.androidsdk.snaphy.snaphyandroidsdk.db;


<%
 /*-------PURE JAVASCRIPT METHODS-------------------*/
 var modelName = model.methods.capitalizeFirstLetter(model.name);
%>


import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.content.ContentValues;
import java.util.HashMap;
import com.google.gson.Gson;
import com.google.gson.LongSerializationPolicy;
import com.google.gson.GsonBuilder;
import android.database.Cursor;
import java.lang.reflect.Method;
import android.util.Log;
import java.util.Map;
import com.androidsdk.snaphy.snaphyandroidsdk.list.DataList;


import com.androidsdk.snaphy.snaphyandroidsdk.callbacks.GetUpdatedQuery;
import com.androidsdk.snaphy.snaphyandroidsdk.callbacks.ObjectCallback;
import com.androidsdk.snaphy.snaphyandroidsdk.callbacks.OnParseCursor;
import com.androidsdk.snaphy.snaphyandroidsdk.list.LazyList;

import com.androidsdk.snaphy.snaphyandroidsdk.models.<%- modelName %>;
//Import self repository..
import com.androidsdk.snaphy.snaphyandroidsdk.repository.<%- modelName %>Repository;
import com.androidsdk.snaphy.snaphyandroidsdk.adapter.SnaphyRestAdapter;

/**
* Created by snaphy on 1/2/2017.
*/

public class <%- modelName %>Db{

    // All Static variables
    SnaphyRestAdapter restAdapter;

    private String TAG = "snaphy";
    private String KEY_ID = "ID";
    private String KEY_OBJECT = "OBJECT";
    private Context context;
    // Database Name
    private static String DATABASE_NAME;

    // Contacts table name
    private static String TABLE;



    public SQLiteDatabase getInstance(){
        SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
        return db;
    }

  public <%- modelName %>Db(Context context, String DATABASE_NAME, SnaphyRestAdapter restAdapter){
    //super(context, DATABASE_NAME, null, DATABASE_VERSION);
    this.context = context;
    this.restAdapter = restAdapter;
    TABLE = "<%- modelName %>";
    this.DATABASE_NAME = DATABASE_NAME;
    SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
    DbHandler.getInstance(context, DATABASE_NAME).onCreate(db);
  }


    public void insert__db (final String id, final <%- modelName %> _modelData) {
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      // Inserting Row
      ContentValues values = getContentValues(_modelData);
      db.insert("`<%- modelName %>`", null, values);
    }





    public ContentValues getContentValues(<%- modelName %> _modelData){
      ContentValues values = new ContentValues();
         <%
          for( let property in model.properties) { -%>
              <% if(model.properties.hasOwnProperty(property)){
                  let isArray = model.properties[property].type instanceof Array;
                  var capitalPropertyName = model.methods.capitalizeFirstLetter(property);
              -%>

                <% if(isArray){ -%>
                  String <%-property%>Data = "";
                  if(_modelData.get<%-capitalPropertyName%>() != null){
                    GsonBuilder gsonBuilder = new GsonBuilder();
                    gsonBuilder.setLongSerializationPolicy(LongSerializationPolicy.STRING);
                    Gson gson = gsonBuilder.create();
                    <%-property%>Data = gson.toJson(_modelData.get<%-capitalPropertyName%>(), DataList.class);
                    values.put("`<%-property%>`", <%-property%>Data);
                  }
              <% }else{ -%>
                    <% if(model.properties[property].type === "string" || model.properties[property].type === "date"){ -%>
                        String <%-property%>Data = "";
                        if(_modelData.get<%-capitalPropertyName%>() != null){
                          <%-property%>Data = _modelData.get<%-capitalPropertyName%>().toString();
                          values.put("`<%-property%>`", <%-property%>Data);
                        }
                    <% }else if(model.properties[property].type === "object" || model.properties[property].type === "geopoint"){ -%>
                        String <%-property%>Data = "";
                        if(_modelData.get<%-capitalPropertyName%>() != null){
                          GsonBuilder gsonBuilder = new GsonBuilder();
                          gsonBuilder.setLongSerializationPolicy(LongSerializationPolicy.STRING);
                          Gson gson = gsonBuilder.create();
                          <%-property%>Data = gson.toJson(_modelData.get<%-capitalPropertyName%>(), HashMap.class);
                          values.put("`<%-property%>`", <%-property%>Data);
                        }
                    <% }else if(model.properties[property].type === "number"){ -%>
                        double <%-property%>Data;
                        <%-property%>Data = (double)_modelData.get<%-capitalPropertyName%>();
                        values.put("`<%-property%>`", <%-property%>Data);
                    <% }else if(model.properties[property].type === "boolean"){ -%>
                        int <%-property%>Data = 0;
                        if(_modelData.get<%-capitalPropertyName%>()){
                          <%-property%>Data = 1;
                        }else{
                          <%-property%>Data = 0;
                        }
                        values.put("`<%-property%>`", <%-property%>Data);
                    <% }else{ -%>
                        //http://stackoverflow.com/questions/160970/how-do-i-invoke-a-java-method-when-given-the-method-name-as-a-string
                        String <%-property%>Data = "";
                        try {
                              Method method = _modelData.getClass().getMethod("get<%-capitalPropertyName%>");
                              if(method.invoke(_modelData) != null){
                                //<%-property%>Data = _modelData.get<%-capitalPropertyName%>().toString();
                                <%-property%>Data = (String) method.invoke(_modelData);
                                values.put("`<%-property%>`", <%-property%>Data);
                              }
                        } catch (Exception e) {
                          Log.e("Database Error", e.toString());
                        }

                    <% } -%>
              <% }//END IF-ELSE -%>

          <% } -%>
        <%}%>
        <%
           function lowercaseFirstLetter(string) {
             return string.charAt(0).toLowerCase() + string.slice(1);
           }
            //Prepare method for get foreign key..
            var getForeignKeyName = function (model, relation) {
              var foreignKey = model.relations[relation].foreignKey;
              if (!foreignKey) {
                foreignKey = lowercaseFirstLetter(model.relations[relation].model) + "Id";
              }
              return foreignKey;
            };
         %>
          <%
            for(var relation in model.relations) {
                if(model.relations.hasOwnProperty(relation)) {
                  if (model.relations[relation].type === "hasOne") {
                  var capitalPropertyName = model.methods.capitalizeFirstLetter(getForeignKeyName(model, relation));
          %>
                    String <%- getForeignKeyName(model, relation) %>Data = "";
                    try {
                        Method method = _modelData.getClass().getMethod("get<%-capitalPropertyName%>");
                        if(method.invoke(_modelData) != null){
                          //<%-getForeignKeyName(model, relation)%>Data = _modelData.get<%-capitalPropertyName%>().toString();
                          <%-getForeignKeyName(model, relation)%>Data = (String) method.invoke(_modelData);
                          values.put("`<%-getForeignKeyName(model, relation)%>`", <%-getForeignKeyName(model, relation)%>Data);
                        }
                    } catch (Exception e) {
                      Log.e("Database Error", e.toString());
                    }
          <%
                  }
                }
            }
          %>
        //Add the updated data property value to be 1
        values.put("`<%- model.methods.updateDataProperty %>`", 1);
        return values;
    }



    // Getting single c
    public   <%- modelName %> get__db(String id) {
        if (id != null) {
            SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();
            Cursor cursor = db.query("<%- modelName %>", null, "id=?", new String[]{id}, null, null, null, null);
            if (cursor != null) {
                if (!cursor.moveToFirst() || cursor.getCount() == 0){
                    return null;
                }else{
                    HashMap<String, Object> hashMap = parseCursor(cursor);
                    cursor.close();
                    //db.close(); // Closing database connection
                    if (hashMap != null) {
                        <%- modelName %>Repository repo = restAdapter.createRepository(<%- modelName %>Repository.class);
                        repo.addStorage(context);
                        return (<%- modelName %>)repo.createObject(hashMap);
                    } else {
                        return null;
                    }
                }

            } else {
                return null;
            }
        } else {
            return null;
        }

    } //get__db




    // Getting single cont
    public   <%- modelName %> get__db(String whereKey, String whereKeyValue) {
        if (whereKeyValue != null) {
            SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();
            Cursor cursor = db.query("`<%- modelName %>`", null, "`" + whereKey + "` =?", new String[]{whereKeyValue}, null, null, null, null);
            if (cursor != null) {
                if (!cursor.moveToFirst() || cursor.getCount() == 0){
                    return null;
                }else{
                    HashMap<String, Object> hashMap = parseCursor(cursor);

                    cursor.close();
                    //db.close(); // Closing database connection

                    if (hashMap != null) {
                        <%- modelName %>Repository repo = restAdapter.createRepository(<%- modelName %>Repository.class);
                        repo.addStorage(context);
                        return (<%- modelName %>)repo.createObject(hashMap);
                    } else {
                        return null;
                    }
                }

            } else {
                return null;
            }
        } else {
            return null;
        }

    } //get__db




    private HashMap<String, Object> parseCursor(Cursor cursor ){
      HashMap<String, Object> hashMap = new HashMap<>();

        <%
          //Increment after each loop
          var id=0;
          for( let property in model.properties) {
        -%>
              <% if(model.properties.hasOwnProperty(property)){
                  let isArray = model.properties[property].type instanceof Array;
                  var capitalPropertyName = model.methods.capitalizeFirstLetter(property);
              -%>

                <% if(isArray){ -%>
                  <%- model.methods.getJavaType(model.properties[property].type[0], isArray) %> <%-property%>Data = new DataList<>();
                  if(cursor.getString(<%- id %>) != null){
                    GsonBuilder gsonBuilder = new GsonBuilder();
                    gsonBuilder.setLongSerializationPolicy(LongSerializationPolicy.STRING);
                    Gson gson = gsonBuilder.create();
                    <%-property%>Data = gson.fromJson(cursor.getString(<%- id %>), DataList.class);
                    if(<%-property%>Data != null){
                      <%-property%>Data = (<%- model.methods.getJavaType(model.properties[property].type[0], isArray) %>)<%-property%>Data;
                      hashMap.put("<%-property%>", <%-property%>Data);
                    }
                  }
              <% }else{ -%>
                    <% if(model.properties[property].type === "string" || model.properties[property].type === "date"){ -%>
                        String <%-property%>Data = "";
                        if(cursor.getString(<%- id %>) != null){
                          <%-property%>Data = cursor.getString(<%- id %>);
                          if(<%-property%>Data != null){
                            <%-property%>Data = (<%- model.methods.getJavaType(model.properties[property].type, false) %>)<%-property%>Data;
                            hashMap.put("<%-property%>", <%-property%>Data);
                          }
                        }
                    <% }else if(model.properties[property].type === "object" || model.properties[property].type === "geopoint"){ -%>
                        <%- model.methods.getJavaType(model.properties[property].type, false) %> <%-property%>Data = new HashMap<>();
                        if(cursor.getString(<%- id %>) != null){
                          GsonBuilder gsonBuilder = new GsonBuilder();
                          gsonBuilder.setLongSerializationPolicy(LongSerializationPolicy.STRING);
                          Gson gson = gsonBuilder.create();
                           <%-property%>Data = gson.fromJson(cursor.getString(<%- id %>), Map.class);
                          if(<%-property%>Data != null){
                            <%-property%>Data = (<%- model.methods.getJavaType(model.properties[property].type, false) %>)<%-property%>Data;
                            hashMap.put("<%-property%>", <%-property%>Data);
                          }
                        }
                    <% }else if(model.properties[property].type === "number"){ -%>
                        double <%-property%>Data = (double)0;
                          <%-property%>Data = cursor.getInt(<%- id %>);
                          <%-property%>Data = (<%- model.methods.getJavaType(model.properties[property].type, false) %>)<%-property%>Data;
                          hashMap.put("<%-property%>", <%-property%>Data);


                    <% }else if(model.properties[property].type === "boolean"){ -%>
                        boolean <%-property%>Data = false;
                        int temp<%-property%>Data = cursor.getInt(<%- id %>);
                        if( temp<%-property%>Data > 0){
                          <%-property%>Data = true;
                        }else{
                          <%-property%>Data = false;
                        }
                        hashMap.put("<%-property%>", <%-property%>Data);
                    <% }else{ -%>
                        String <%-property%>Data = "";
                        if(cursor.getString(<%- id %>) != null){
                          <%-property%>Data = cursor.getString(<%- id %>);
                          if(<%-property%>Data != null){
                            <%-property%>Data = <%-property%>Data.toString();
                            hashMap.put("<%-property%>", <%-property%>Data);
                          }
                        }
                    <% } -%>
              <% }//END IF-ELSE -%>
              <% id++; %>
          <% } -%>
        <%}%>//End for loop
         <%
           function lowercaseFirstLetter(string) {
             return string.charAt(0).toLowerCase() + string.slice(1);
           }
            //Prepare method for get foreign key..
            var getForeignKeyName = function (model, relation) {
              var foreignKey = model.relations[relation].foreignKey;
              if (!foreignKey) {
                foreignKey = lowercaseFirstLetter(model.relations[relation].model) + "Id";
              }
              return foreignKey;
            };
         %>
          <%
            for(var relation in model.relations) {
                if(model.relations.hasOwnProperty(relation)) {
                  if (model.relations[relation].type === "hasOne") {
                  var capitalPropertyName = model.methods.capitalizeFirstLetter(getForeignKeyName(model, relation));
          %>
                    String <%-getForeignKeyName(model, relation)%>Data = "";
                    int <%-getForeignKeyName(model, relation)%>index = cursor.getColumnIndex("<%-getForeignKeyName(model, relation)%>");
                    if(<%-getForeignKeyName(model, relation)%>index >= 0){

                        if(cursor.getString(<%-getForeignKeyName(model, relation)%>index) != null){
                          <%-getForeignKeyName(model, relation)%>Data = cursor.getString(<%-getForeignKeyName(model, relation)%>index);
                          if(<%-getForeignKeyName(model, relation)%>Data != null){
                            <%-getForeignKeyName(model, relation)%>Data = <%-getForeignKeyName(model, relation)%>Data.toString();
                            hashMap.put("<%-getForeignKeyName(model, relation)%>", <%-getForeignKeyName(model, relation)%>Data);
                          }
                        }

                    }

          <%
                  }
                }
            }
          %>

        return hashMap;
    }//parseCursor



    public void upsert__db(String id, <%- modelName %> model){
        if(count__db(id) != 0){
            update__db(id, model);
        }else{
            insert__db(id, model);
        }
    } //upsert__db



    // Getting All Contacts
    public DataList<<%- modelName %>>  getAll__db() {
        DataList<<%- modelName %>> modelList = new DataList<<%- modelName %>>();
        // Select All Query
        String selectQuery = "SELECT  * FROM `<%- modelName %>`";

        SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();
        //http://www.tothenew.com/blog/sqlite-locking-and-transaction-handling-in-android/
        Cursor cursor = db.rawQuery(selectQuery, null);
        if (!cursor.moveToFirst() || cursor.getCount() == 0){
            return (DataList<<%- modelName %>>) modelList;
        }else{
            do {

                HashMap<String, Object> hashMap = parseCursor(cursor);
                if(hashMap != null){
                    <%- modelName %>Repository repo = restAdapter.createRepository(<%- modelName %>Repository.class);
                    repo.addStorage(context);
                    modelList.add((<%- modelName %>)repo.createObject(hashMap));
                }
            } while (cursor.moveToNext());
        }
        cursor.close();
        //db.close();
        // return contact list
        return (DataList<<%- modelName %>>) modelList;
    }


    //https://dmytrodanylyk.com/articles/lazy-sqlite/
    // Getting All Data where and sort column according to date wise..
    /**
     * Fetch the patient group by lazy data..
     * @param limit
     * @param skip
     * @return
     */
    public LazyList<<%- modelName %>> getAll__lazy(final int limit, final int skip, ObjectCallback<<%- modelName %>> callback, final GetUpdatedQuery getUpdatedQuery, final OnParseCursor onParseCursor) {


        SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();

        final <%- modelName %>Repository repo = restAdapter.createRepository(<%- modelName %>Repository.class);
        repo.addStorage(context);
        return new LazyList<>(db, new LazyList.ItemFactory<<%- modelName %>>() {
            @Override
            public <%- modelName %> create(Cursor cursor, int index) {
                <%- modelName %> data;
                cursor.moveToPosition(index);
                HashMap<String, Object> hashMap = onParseCursor.parseCursor(cursor);
                data = (<%- modelName %>)repo.createObject(hashMap);
                return data;
            }
        }, callback, new LazyList.OnQueryChange(){
            @Override
            public String getUpdateQuery() {
                String orderBy = getUpdatedQuery.onOrderByChange();
                //Get Where Key Value..
                HashMap<String, Object> getWhereKeyValue = getUpdatedQuery.onQueryChange();

                String whereQuery = getWhereQuery(getWhereKeyValue);
                String selectQuery;
                if(orderBy != null){
                    selectQuery = "SELECT  * FROM `<%- modelName %>` " + whereQuery  + " ORDER BY " + orderBy ;
                    if(limit != 0){
                        // Select All Query
                        selectQuery = selectQuery +  " " + " LIMIT " + limit + " OFFSET " + skip;
                    }else{
                        selectQuery = selectQuery +  " " + " LIMIT -1 OFFSET " + skip;
                    }
                }else{
                    if(limit != 0){
                        // Select All Query
                        selectQuery = "SELECT  * FROM <%- modelName %> " + whereQuery + " LIMIT " + limit + " OFFSET " + skip;
                    }else{
                        selectQuery = "SELECT  * FROM <%- modelName %> " + whereQuery  + " LIMIT -1 OFFSET " + skip;
                    }
                }

                return selectQuery;
            }
        });
    }




    public <%- modelName %> get__db(String id, OnParseCursor onParseCursor){
        if (id != null) {
            SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();
            Cursor cursor = db.query("<%- modelName %>", null, "id=?", new String[]{id}, null, null, null, null);
            if (cursor != null) {
                if (!cursor.moveToFirst() || cursor.getCount() == 0){
                    return null;
                }else{
                    HashMap<String, Object> hashMap = onParseCursor.parseCursor(cursor);
                    cursor.close();
                    //db.close(); // Closing database connection
                    if (hashMap != null) {
                        <%- modelName %>Repository repo = restAdapter.createRepository(<%- modelName %>Repository.class);
                        repo.addStorage(context);
                        return (<%- modelName %>)repo.createObject(hashMap);
                    } else {
                        return null;
                    }
                }
            } else {
                return null;
            }
        } else {
            return null;
        }
    }




    public String getWhereQuery(HashMap<String, Object> whereKeyValue){
        //Prepare where key value
        String where = "";
        if(whereKeyValue.size() > 0){
            where = where +  " WHERE ";
        }
        where = where + getWhere(whereKeyValue);
        return where;
    }


     //Now also accept gt and lt values
     public String getWhere(HashMap<String, Object> whereKeyValue){
        String where = "";
        int i=0;
        for(String key : whereKeyValue.keySet()){
            Object o = whereKeyValue.get(key);
            DataList<String> keyValue = getKeyValue(key, o);
            if(keyValue != null){
                if(keyValue.size() != 0){
                    String returnedKey = keyValue.get(0);
                    try{
                        int value = Integer.parseInt(keyValue.get(1));
                        if(i==0){
                            if(returnedKey.equals("gt")){
                                where = where + " `" + key + "` > "+ value + "";
                            }else if(returnedKey.equals("lt")){
                                where = where + " `" + key + "` < "+ value + "";
                            }else{
                                where = where + " `" + key + "` = "+ value + "";
                            }
                        }else{
                            if(returnedKey.equals("gt")){
                                where = where + " AND `" + key + "` > "+ value + "";
                            }else if(returnedKey.equals("lt")){
                                where = where + " AND `" + key + "` < "+ value + "";
                            }else{
                                where = where + " AND `" + key + "` = "+ value + "";
                            }
                        }

                    }catch(Exception e){
                      String value = keyValue.get(1);
                      if(i==0){
                          if(returnedKey.equals("gt")){
                              where = where + " `" + key + "` > '"+ value + "'";
                          }else if(returnedKey.equals("lt")){
                              where = where + " `" + key + "` < '"+ value + "'";
                          }else{
                              where = where + " `" + key + "` = '"+ value + "'";
                          }
                      }else{
                          if(returnedKey.equals("gt")){
                              where = where + " AND `" + key + "` > '"+ value + "'";
                          }else if(returnedKey.equals("lt")){
                              where = where + " AND `" + key + "` < '"+ value + "'";
                          }else{
                              where = where + " AND `" + key + "` = '"+ value + "'";
                          }
                      }

                    }

                    i++;
                }
            }
        }
        return where;
     }




    //first argument is key and second is value
    public DataList<String> getKeyValue(String key, Object keyValue){
        DataList<String> returnVal = new DataList<>();
        try{
            //Converting to nested hashmap
            HashMap<String, Object> value = (HashMap<String, Object>)keyValue;
            for(String key_ : value.keySet()){
                Object o = value.get(key_);
                returnVal.add(key_);
                returnVal.add(o.toString());
                return returnVal;
            }
        }catch(Exception e){
            returnVal.add(key);
            returnVal.add(keyValue.toString());
            return returnVal;
        }
        return null;
    }



    // Getting All Data where
    public DataList<<%- modelName %>>  getAll__db(HashMap<String, Object> whereKeyValue) {
        return getAll__db(whereKeyValue, null, 0, 0);
    }



    // Getting All Data where and sort column according to date wise..
    public DataList<<%- modelName %>>  getAll__db(HashMap<String, Object> whereKeyValue, String orderBy, int limit, int skip) {
        DataList<<%- modelName %>> modelList = new DataList<<%- modelName %>>();
        String whereQuery = getWhereQuery(whereKeyValue);
        String selectQuery;
        if(orderBy != null){
            selectQuery = "SELECT  * FROM `<%- modelName %>` " + whereQuery  + " ORDER BY " + orderBy ;
            if(limit != 0){
                // Select All Query
                selectQuery = selectQuery +  " " + " LIMIT " + limit + " OFFSET " + skip;
            }else{
                selectQuery = selectQuery +  " " + " LIMIT -1 OFFSET " + skip;
            }
        }else{
            if(limit != 0){
                // Select All Query
                selectQuery = "SELECT  * FROM <%- modelName %> " + whereQuery + " LIMIT " + limit + " OFFSET " + skip;
            }else{
                selectQuery = "SELECT  * FROM <%- modelName %> " + whereQuery  + " LIMIT -1 OFFSET " + skip;
            }
        }

        SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();
        //http://www.tothenew.com/blog/sqlite-locking-and-transaction-handling-in-android/
        Cursor cursor = db.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
         if (!cursor.moveToFirst() || cursor.getCount() == 0){
            return (DataList<<%- modelName %>>) modelList;
         }else{
            do {

                HashMap<String, Object> hashMap = parseCursor(cursor);
                if(hashMap != null){
                    <%- modelName %>Repository repo = restAdapter.createRepository(<%- modelName %>Repository.class);
                    repo.addStorage(context);
                    modelList.add((<%- modelName %>)repo.createObject(hashMap));
                }
            } while (cursor.moveToNext());
         }
        cursor.close();
        // return contact list
        return (DataList<<%- modelName %>>) modelList;
    }



    // Getting All Data where
    public DataList<<%- modelName %>>  getAll__db(HashMap<String, Object> whereKeyValue, int limit, int skip) {
        return getAll__db(whereKeyValue, null,  limit, skip);
    }





    /**
     * Check count of database.
     * @param whereKeyValue
     * @param orderBy
     * @param limit
     * @return
     */
    public int count__db(HashMap<String, Object> whereKeyValue, String orderBy, int limit, int skip){
        String whereQuery = getWhereQuery(whereKeyValue);
        String countQuery;
        if(orderBy != null){
            countQuery = "SELECT  * FROM `<%- modelName %>` " + whereQuery  + " ORDER BY " + orderBy ;
            if(limit != 0){
                // Select All Query
                countQuery = countQuery +  " " + " LIMIT " + limit + " OFFSET " + skip;
            }else{
                countQuery = countQuery + " LIMIT -1  OFFSET " + skip;
            }
        }else{
            if(limit != 0){
                // Select All Query
                countQuery = "SELECT  * FROM `<%- modelName %>` " + whereQuery + " LIMIT " + limit + " OFFSET " + skip;
            }else{
                countQuery = "SELECT  * FROM `<%- modelName %>` " + whereQuery + " LIMIT -1 OFFSET " + skip;
            }
        }


        SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
        int count = cursor.getCount();
        cursor.close();
        return count;
    }



    /**
     * Check count of database.
     * @param whereKeyValue
     * @param limit
     * @return
     */
    public int count__db(HashMap<String, Object> whereKeyValue, int limit, int skip){
        String whereQuery = getWhereQuery(whereKeyValue);
        String countQuery;
        if(limit != 0){
            countQuery = "SELECT  * FROM `<%- modelName %>` " + whereQuery + " LIMIT " + limit + " OFFSET " + skip;
        }else{
            countQuery = "SELECT  * FROM `<%- modelName %>` " + whereQuery + " LIMIT -1 OFFSET " + skip;
        }

        SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
        int count = cursor.getCount();
        cursor.close();
        return count;
    }


    /**
     * Check count of database.
     * @param whereKeyValue
     * @return
     */
    public int count__db(HashMap<String, Object> whereKeyValue){
            return count__db(whereKeyValue, 0, 0);
    }



    // Updating updated data property to new contact with where clause..
    public void checkOldData__db(final HashMap<String, Object> whereKeyValue) {
            SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
            //http://www.tothenew.com/blog/sqlite-locking-and-transaction-handling-in-android/
            ContentValues values = new ContentValues();
            values.put("_DATA_UPDATED", 0);
            String where = getWhere(whereKeyValue);
            // updating row
            db.update("`<%- modelName %>`", values, "_DATA_UPDATED = 1 AND " + where, null);
    }


    // Delete Old data with where clause
    public void deleteOldData__db(final HashMap<String, Object> whereKeyValue) {
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      String where = getWhere(whereKeyValue);
      db.delete("`<%- modelName %>`", "_DATA_UPDATED = 0 AND " + where , null);
    }





    // Deleting by whereKeyValue filter data present..
    public void delete__db(final HashMap<String, Object> whereKeyValue) {
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      String where = getWhere(whereKeyValue);
      db.delete("`<%- modelName %>`", where , null);
    }







    // Getting All Data where
    public DataList<<%- modelName %>>  getAll__db(String whereKey, String whereKeyValue) {
        DataList<<%- modelName %>> modelList = new DataList<<%- modelName %>>();
        // Select All Query
        String selectQuery = "SELECT  * FROM `<%- modelName %>` WHERE `" + whereKey +"` ='"+ whereKeyValue + "'" ;

        SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
         if (!cursor.moveToFirst() || cursor.getCount() == 0){
            return (DataList<<%- modelName %>>) modelList;
         }else{
            do {

                HashMap<String, Object> hashMap = parseCursor(cursor);
                if(hashMap != null){
                    <%- modelName %>Repository repo = restAdapter.createRepository(<%- modelName %>Repository.class);
                    repo.addStorage(context);
                    modelList.add((<%- modelName %>)repo.createObject(hashMap));
                }
            } while (cursor.moveToNext());
         }
        cursor.close();
        return (DataList<<%- modelName %>>) modelList;
    }



    /**
     * Check count of database.
     * @param whereKey
     * @param whereKeyValue
     * @return
     */
    public int count__db(String whereKey, String whereKeyValue){
      String countQuery = "SELECT  * FROM `<%- modelName %>` WHERE `" + whereKey +"` ='"+ whereKeyValue + "'" ;
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();
      Cursor cursor = db.rawQuery(countQuery, null);
      int count = cursor.getCount();
      cursor.close();
      return count;
    }


    // Updating updated data property to new contact with where clause..
    public void checkOldData__db(final String whereKey, final String whereKeyValue) {
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      ContentValues values = new ContentValues();
      values.put("_DATA_UPDATED", 0);
      // updating row
      db.update("`<%- modelName %>`", values, "_DATA_UPDATED = 1 AND `" + whereKey + "` = ?", new String[]{whereKeyValue});
    }


    // Delete Old data with where clause
    public void deleteOldData__db(final String whereKey, final String whereKeyValue) {
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      db.delete("`<%- modelName %>`", "_DATA_UPDATED = 0 AND `" + whereKey + "` = ?", new String[]{whereKeyValue});
    }


    //Update multiple data at once..
    public void updateAll__db(final HashMap<String, Object> whereKeyValue, final <%- modelName %> _modelData ){
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      ContentValues values = getContentValues(_modelData);
      String where = getWhere(whereKeyValue);
      db.update("`<%- modelName %>`", values, where, null);
    }




    // Deleting by whereKey and whereKeyValue
    public void delete__db(final String whereKey, final String whereKeyValue) {
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      db.delete(TABLE, whereKey + " = ?", new String[]{whereKeyValue});
    }



    // Updating single contact
    public void update__db(final String id,   final <%- modelName %> _modelData) {
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      ContentValues values = getContentValues(_modelData);
      // updating row
      db.update("`<%- modelName %>`", values, "id = ?", new String[] { id });
    }


    // Updating updated data property to new contact
    public void checkOldData__db() {
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      ContentValues values = new ContentValues();
      values.put("<%- model.methods.updateDataProperty %>", 0);
      // updating row
      db.update("`<%- modelName %>`", values, "<%- model.methods.updateDataProperty %> = 1", null);
    }


    // Delete Old data
    public void deleteOldData__db() {
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      db.delete("`<%- modelName %>`", "<%- model.methods.updateDataProperty %> = 0", null);
    }


    // Getting contacts Count
    public int count__db() {
        String countQuery = "SELECT  * FROM `" + TABLE + "`";
        SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
        int count = cursor.getCount();
        cursor.close();
        // return count
        return count;
    }


    /**
     * Get count by Id..
     * @param id
     * @return
     */
    public int count__db(String id){
        String countQuery = "SELECT  * FROM `" + TABLE  + "` WHERE ID='" + id+"'";
        SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
        int count = cursor.getCount();
        cursor.close();
        // return count
        return count;
    }



    // Deleting by id
    public void delete__db(final String id) {
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      db.delete(TABLE, KEY_ID + " = ?",
      new String[] { id });
    }

    public void reset__db(){
      SQLiteDatabase db = DbHandler.getInstance(context, DATABASE_NAME).getWritableDatabase();
      db.delete(TABLE,null,null);
    }

}
