Monday 25 April 2016

Database Operation Manager ( insert ,update, delete and find) like a pro for Sqlite Android.

This post deals with sql database operation simplification all at one place.

For database operation we mainly need a method that returns ContentValues (For insert and update) and Constraints( for update and delete and find) and a method called contentToModel that returns data in list containing each row data as a model ( List<TableRow> )

TableRow.java class was an abstract class containing method to return ContentValues, say modelToContentValues()


/**
 * Created by Naresh on 22/03/16.
 */
public abstract class TableRow{
    @NonNull
    public abstract ContentValues modelToContentValues();
}


DatabaseOperationManager.java is the class that contains all basic database operations

public abstract class DatabaseOperation<T extends TableRow> {
    SQLiteDatabase database;
    String table_name;

    public DatabaseOperation(SQLiteDatabase database, String table_name) {
        this.database = database;
        this.table_name = table_name;
    }

    public long insert(T row) {
        return database.insert(table_name, null, row.modelToContentValues());
    }

    public List<T> all() {
        return all(null);
    }

    public List<T> all(String sort_by) {
        Cursor cursor = database.query(table_name, new String[]{"*"}, null, null, null, null, sort_by);
        return cursorToModel(cursor);
    }

    public abstract int update(T row);

    public int update(T row, String constraint) {
        ContentValues values = row.modelToContentValues();
        return database.update(table_name, values, constraint, null);
    }

    public List<T> find(String[] constraint_columns, Object[] constraint_values) throws Exception {
        String where_clause;
        if (constraint_columns == null && constraint_values == null)
            return all();
        else if (constraint_columns == null) {
            throw new Exception("invalid column names");
        } else if (constraint_columns.length != constraint_values.length)
            throw new Exception("constraint columns and constrain values size are not matched");
        else {
            if (constraint_columns[0] == null)
                throw new Exception("Invalid column null at position 0");
            where_clause = constraint_columns[0] + (constraint_values[0] == null ? "" : (constraint_values[0] instanceof Number ? " = " : " like \"") + constraint_values[0] + (constraint_values[0] instanceof Number ? "" : "\""));
            for (int i = 1; i < constraint_columns.length; i++) {
                if (constraint_columns[i] == null)
                    throw new Exception("Invalid column null at position " + i);
                where_clause = where_clause + " and " + constraint_columns[i] + (constraint_values[i] == null ? "" : " like \"") + constraint_values[i] + (constraint_values[i] instanceof Number ? "" : "\"");
            }
        }
        String[] columns = new String[]{"*"};
        Cursor cursor = database.query(table_name, columns, where_clause, null, null, null, null);
        return cursorToModel(cursor);
    }

    public int delete(String where_clause) {
        return database.delete(table_name, where_clause, null);
    }

    public int clear() {
        return delete("1");
    }


    @NonNull
    public abstract List<T> cursorToModel(Cursor cursor);
}

the thing you need t do are much simpler just extend these two classes like this

/**
 * Created by Naresh on 23/04/16.
 */
public class PatientStatus extends TableRow {
    Integer id;
    String status_code;
    String status_name;
    String status_description;
    String next_step;
    String created_at;
    String updated_at;

    public void setId(Integer id) {
        this.id = id;
    }
    public void setStatus_code(String status_code) {
        this.status_code = status_code;
    }

    public void setStatus_name(String status_name) {
        this.status_name = status_name;
    }

    public void setStatus_description(String status_description) {
        this.status_description = status_description;
    }

    public void setNext_step(String next_step) {
        this.next_step = next_step;
    }

    public void setCreated_at(String created_at) {
        this.created_at = created_at;
    }

    public void setUpdated_at(String updated_at) {
        this.updated_at = updated_at;
    }


    @NonNull
    @Override
    public ContentValues modelToContentValues() {
        ContentValues values = new ContentValues();
        if (id != null)
            values.put("ID", id);
        if (status_code != null)
            values.put("STATUS_CODE", status_code);
        if (status_name != null)
            values.put("STATUS_NAME", status_name);
        if (status_description != null)
            values.put("STATUS_DESCRIPTION", status_description);
        if (next_step != null)
            values.put("NEXT_STEP", next_step);
        if (created_at != null)
            values.put("CREATED_ON", created_at);
        if (updated_at != null)
            values.put("UPDATED_ON", updated_at);
        return values;
    }
}


and 


/**
 * Created by Naresh on 23/04/16.
 */
public class StatusOperation extends DatabaseOperation<Status> {
    public StatusMasterOperation(SQLiteDatabase database) {
        super(database, "STATUS_TABLE");
    }

    @Override
    public int update(Status row) {
        return update(row, "ID" + " = \"" + row.getId() + "\"");
    }

    @NonNull
    @Override
    public List<Status> cursorToModel(Cursor cursor) {
        List<Status> list = new ArrayList<>();
        while (cursor.moveToNext()) {
            Status status = new Status();
            int index = cursor.getColumnIndex("ID");
            if (index != -1)
                if (cursor.getType(index) != Cursor.FIELD_TYPE_NULL) {
                    status.setId(cursor.getInt(index));
                }
            index = cursor.getColumnIndex("STATUS_CODE");
            if (index != -1)
                if (cursor.getType(index) != Cursor.FIELD_TYPE_NULL) {
                    status.setStatus_code(cursor.getString(index));
                }
            index = cursor.getColumnIndex("STATUS_NAME");
            if (index != -1)
                if (cursor.getType(index) != Cursor.FIELD_TYPE_NULL) {
                    status.setStatus_name(cursor.getString(index));
                }
            index = cursor.getColumnIndex("STATUS_DESCRIPTION");
            if (index != -1)
                if (cursor.getType(index) != Cursor.FIELD_TYPE_NULL) {
                    status.setStatus_description(cursor.getString(index));
                }
            index = cursor.getColumnIndex("NEXT_STEP");
            if (index != -1)
                if (cursor.getType(index) != Cursor.FIELD_TYPE_NULL) {
                    status.setNext_step(cursor.getString(index));
                }
            index = cursor.getColumnIndex("CREATED_ON");
            if (index != -1)
                if (cursor.getType(index) != Cursor.FIELD_TYPE_NULL) {
                    status.setCreated_at(cursor.getString(index));
                }
            index = cursor.getColumnIndex("UPDATED_ON");
            if (index != -1)
                if (cursor.getType(index) != Cursor.FIELD_TYPE_NULL) {
                    status.setUpdated_at(cursor.getString(index));
                }
            list.add(status);
        }
        return list;
    }
}



Hope this helpful for database operation management.

Thank you. 

Tuesday 2 February 2016

Android Auto Horizontal Scrolling TextView (marquee)

 import android.content.Context;
 import android.graphics.Rect;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.widget.TextView;

 /**
  * Created by Naresh Katta
  */

 public class MarqueeTextView extends TextView {
 
     public MarqueeTextView(Context context) {
         super(context);
         init();
     }

     public MarqueeTextView(Context context, AttributeSet attrs) {
         super(context, attrs);
         init();
     }

     public MarqueeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         init();
     }

     private void init() {
         setEllipsize(TextUtils.TruncateAt.MARQUEE);
         setMarqueeRepeatLimit(-1);
         setSelected(true);
     }

     @Override   
     protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
         if (focused)
             super.onFocusChanged(true, direction, previouslyFocusedRect);
     }

     @Override    
     public void onWindowFocusChanged(boolean focused) {
         if (focused)
             super.onWindowFocusChanged(true);
     }

     @Override    
     public boolean isFocused() {
         return true;
     }

    //note this file has some limitations see comments of this answer for more details of limitations
}