package org.sagemath.droid.database;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import org.sagemath.droid.R;
import org.sagemath.droid.models.database.Cell;
import org.sagemath.droid.models.database.Group;
import org.sagemath.droid.models.database.Insert;
import org.sagemath.droid.utils.FileXMLParser;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import static nl.qbusict.cupboard.CupboardFactory.cupboard;
/**
* SQLiteHelper for this app, uses Cupboard instead of general SQL statements
*
* @author Nikhil Peter Raj
*/
public class SageSQLiteOpenHelper extends SQLiteOpenHelper {
private static final String TAG = "SageDroid:SageSQLiteOpenHelper";
private static SageSQLiteOpenHelper instance = null;
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "sagedroid.db";
private Context context;
private List<Group> currentGroups;
static {
cupboard().register(Cell.class);
cupboard().register(Group.class);
cupboard().register(Insert.class);
}
public static SageSQLiteOpenHelper getInstance(Context context) {
if (instance == null) {
instance = new SageSQLiteOpenHelper(context.getApplicationContext());
}
return instance;
}
private SageSQLiteOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context.getApplicationContext();
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "Creating tables");
cupboard().withDatabase(db).createTables();
InputStream inputStream = context.getResources().openRawResource(R.raw.cell_collection);
FileXMLParser parser = new FileXMLParser();
parser.parse(inputStream);
List<Cell> initialCells = parser.getIntitalCells();
List<Group> initialGroups = parser.getInitialGroups();
addInitialGroups(initialGroups, db);
addInitialCells(initialCells, db);
addInitialInserts(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//Not sure if this is alright...
//cupboard().withDatabase(getWritableDatabase()).dropAllTables();
Log.i(TAG, "In onUpgrade");
onCreate(getWritableDatabase());
}
public Long addCell(Cell cell) {
Log.i(TAG, "Adding cell: " + cell);
try {
currentGroups = getGroups();
if (currentGroups.contains(cell.getGroup())) {
cell.setGroup(currentGroups.get(currentGroups.indexOf(cell.getGroup())));
}
return cupboard().withDatabase(getWritableDatabase()).put(cell);
} catch (Exception e) {
Log.e(TAG, "Unable to add cell: " + e);
}
return null;
}
private void addInitialInserts(SQLiteDatabase db) {
Insert insert1 = new Insert();
insert1.setInsertDescription("List Comprehension");
insert1.setInsertText("[ i for i in range(0,10) ]");
insert1.setFavorite(false);
Insert insert2 = new Insert();
insert2.setInsertDescription("For Loop");
insert2.setInsertText("for i in range(0,10):");
insert2.setFavorite(false);
cupboard().withDatabase(db).put(insert1, insert2);
}
public void addInitialGroups(List<Group> groups, SQLiteDatabase db) {
Log.i(TAG, "Adding Initial Groups" + groups.toString());
try {
db.beginTransaction();
for (Group group : groups) {
cupboard().withDatabase(db).put(group);
}
db.setTransactionSuccessful();
} catch (Exception e) {
Log.e(TAG, e + "");
} finally {
if (db != null) {
db.endTransaction();
}
}
}
public void addInitialCells(List<Cell> cells, SQLiteDatabase db) {
try {
currentGroups = getGroups(db);
db.beginTransaction();
for (Cell cell : cells) {
if (!currentGroups.contains(cell.getGroup())) {
cupboard().withDatabase(db).put(cell);
} else {
Group group = currentGroups.get(currentGroups.indexOf(cell.getGroup()));
cell.setGroup(group);
cupboard().withDatabase(db).put(cell);
}
}
db.setTransactionSuccessful();
} catch (Exception e) {
Log.e(TAG, e + "");
} finally {
if (db != null) {
db.endTransaction();
}
}
}
public List<Cell> getCellsWithGroup(Group group) {
List<Cell> list = null;
try {
list = cupboard()
.withDatabase(getReadableDatabase())
.query(Cell.class)
.withSelection("cellGroup = ?", String.valueOf(group.getId()))
.orderBy("title asc")
.query()
.list();
} catch (Exception e) {
Log.e(TAG, e + "");
}
list = sortCellsByFavorite(list);
return list;
}
public List<Cell> getQueryCells(Group group, String titleQuery) {
String queryFormat = "%" + titleQuery + "%";
List<Cell> list = null;
try {
list = cupboard()
.withDatabase(getReadableDatabase())
.query(Cell.class)
.withSelection("cellGroup = ? AND title LIKE ?", String.valueOf(group.getId()), queryFormat)
.orderBy("title asc")
.query()
.list();
} catch (Exception e) {
Log.e(TAG, e + "");
}
list = sortCellsByFavorite(list);
return list;
}
public List<Group> getGroups(SQLiteDatabase db) {
List<Group> list = null;
try {
list = cupboard()
.withDatabase(db)
.query(Group.class)
.orderBy("cellGroup asc")
.distinct()
.query()
.list();
} catch (Exception e) {
Log.e(TAG, e + "");
}
return list;
}
public List<Group> getGroups() {
List<Group> list = null;
try {
list = cupboard()
.withDatabase(getReadableDatabase())
.query(Group.class)
.orderBy("cellGroup asc")
.distinct()
.query()
.list();
} catch (Exception e) {
Log.e(TAG, e + "");
}
return list;
}
public void addGroup(Group group) {
try {
//If the group is duplicate, discard
List<Group> currentGroups = getGroups();
if (!currentGroups.contains(group))
cupboard().withDatabase(getWritableDatabase()).put(group);
} catch (Exception e) {
Log.e(TAG, e + "");
}
}
public void deleteGroup(Group group) {
try {
//Delete all cells with this group
List<Cell> cells = getCellsWithGroup(group);
Log.i(TAG, "Deleting " + cells.size() + "cells and group: " + group.getCellGroup());
deleteCells(cells);
//Delete the group
cupboard().withDatabase(getWritableDatabase()).delete(group);
} catch (Exception e) {
Log.e(TAG, e + "");
}
}
public void saveGroup(Group group) {
try {
cupboard().withDatabase(getWritableDatabase()).put(group);
} catch (Exception e) {
Log.e(TAG, e + "");
}
}
public List<Insert> getQueryInserts(String query) {
String queryInsert = "%" + query + "%";
List<Insert> inserts = null;
try {
inserts = cupboard()
.withDatabase(getReadableDatabase())
.query(Insert.class)
.withSelection("insertDescription LIKE ?", queryInsert)
.orderBy("insertDescription asc")
.query()
.list();
} catch (Exception e) {
Log.e(TAG, e + "");
}
return inserts;
}
public List<Insert> getInserts() {
List<Insert> inserts = null;
try {
inserts = cupboard()
.withDatabase(getReadableDatabase())
.query(Insert.class)
.orderBy("insertDescription asc")
.query()
.list();
} catch (Exception e) {
Log.e(TAG, e + "");
}
if (inserts != null) {
inserts = sortInsertsByFavorite(inserts);
}
return inserts;
}
public void addInsert(Insert insert) {
try {
cupboard().withDatabase(getWritableDatabase()).put(insert);
} catch (Exception e) {
Log.e(TAG, e + "");
}
}
public boolean addInsert(List<Insert> inserts) {
SQLiteDatabase db = getWritableDatabase();
try {
db.beginTransaction();
for (Insert insert : inserts) {
cupboard().withDatabase(db).put(inserts);
}
db.setTransactionSuccessful();
} catch (Exception e) {
Log.e(TAG, e + "");
return false;
} finally {
db.endTransaction();
return true;
}
}
public void deleteInsert(Insert insert) {
try {
cupboard().withDatabase(getWritableDatabase()).delete(insert);
} catch (Exception e) {
Log.e(TAG, e + "");
}
}
public boolean deleteInsert(List<Insert> inserts) {
SQLiteDatabase db = getWritableDatabase();
try {
db.beginTransaction();
for (Insert insert : inserts) {
Log.i(TAG, "Deleting:" + insert);
cupboard().withDatabase(db).delete(insert);
}
db.setTransactionSuccessful();
} catch (Exception e) {
Log.e(TAG, e + "");
return false;
} finally {
db.endTransaction();
}
return true;
}
private List<Cell> sortCellsByFavorite(List<Cell> cells) {
ArrayList<Cell> favs = new ArrayList<>();
ArrayList<Cell> others = new ArrayList<>();
for (Cell cell : cells) {
if (cell.isFavorite())
favs.add(cell);
else
others.add(cell);
}
favs.addAll(others);
return favs;
}
private List<Insert> sortInsertsByFavorite(List<Insert> inserts) {
ArrayList<Insert> favs = new ArrayList<>();
ArrayList<Insert> others = new ArrayList<>();
for (Insert insert : inserts) {
if (insert.isFavorite()) {
favs.add(insert);
} else {
others.add(insert);
}
}
favs.addAll(others);
return favs;
}
public void saveEditedCell(Cell cell) {
currentGroups = getGroups();
if (currentGroups.contains(cell.getGroup())) {
cell.setGroup(currentGroups.get(currentGroups.indexOf(cell.getGroup())));
}
cupboard().withDatabase(getWritableDatabase()).put(cell);
}
public void saveEditedCells(List<Cell> cells) {
for (Cell cell : cells) {
saveEditedCell(cell);
}
}
public Cell getCellbyID(Long id) {
return cupboard().withDatabase(getReadableDatabase()).get(Cell.class, id);
}
public void deleteCell(Cell cell) {
cupboard().withDatabase(getWritableDatabase()).delete(cell);
}
public boolean deleteCells(List<Cell> cells) {
SQLiteDatabase db = getWritableDatabase();
try {
db.beginTransaction();
for (Cell cell : cells) {
cupboard().withDatabase(getWritableDatabase()).delete(cell);
}
db.setTransactionSuccessful();
} catch (Exception e) {
Log.e(TAG, e + "");
return false;
} finally {
db.endTransaction();
}
return true;
}
}