package com.masterofcode.android.magreader.search;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import com.masterofcode.android.magreader.utils.constants.Constants;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class FeedSearchDbAdapter {
public static final String LOG_TAG = "FeddSearch";
private static final String DATABASE_NAME = "FeedSearch_db";
private static final int DATABASE_VERSION = 1; // Our internal database version (e.g. to control upgrades)
private static final String TABLE_NAME = "feed_for_search_tbl";
public static final String KEY_ID = "id";
public static final String KEY_FEED_TEXT = "feed_text";
public static final String KEY_FEED_GUID = "email";
public static long GENERIC_ERROR = -1;
public static long GENERIC_NO_RESULTS = -2;
public static long ROW_INSERT_FAILED = -3;
private final Context context;
private DbHelper dbHelper;
private SQLiteDatabase sqlDatabase;
public FeedSearchDbAdapter(Context context) {
this.context = context;
}
private static class DbHelper extends SQLiteOpenHelper {
private boolean databaseCreated=false;
DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
if(Constants.Debug)
if(Constants.Debug) Log.d(LOG_TAG, "Creating the application database");
try{
// Create the full text search 3 virtual table
db.execSQL(
"CREATE VIRTUAL TABLE ["+TABLE_NAME+"] USING FTS3 (" +
// "["+KEY_ID+"] INTEGER," +
"["+KEY_FEED_GUID+"] VARCHAR(100)," +
"["+KEY_FEED_TEXT+"] TEXT" +
");"
);
this.databaseCreated = true;
} catch (Exception e) {
Log.e(LOG_TAG, "An error occurred while creating the database: "+e.toString(), e);
this.deleteDatabaseStructure(db);
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(Constants.Debug)
Log.d(LOG_TAG, "Updating the database from the version " + oldVersion + " to " + newVersion + "...");
this.deleteDatabaseStructure(db); // in this example we purge the previous data on upgrade
this.onCreate(db);
}
public boolean databaseCreated(){
return this.databaseCreated;
}
private boolean deleteDatabaseStructure(SQLiteDatabase db){
try{
db.execSQL("DROP TABLE IF EXISTS ["+TABLE_NAME+"];");
return true;
}catch (Exception e) {
Log.e(LOG_TAG, "An error occurred while deleting the database: "+e.toString(), e);
}
return false;
}
}
/**
* Open the database; if the database can't be opened, try to create it
*
* @return {@link Boolean} true if the database was successfuly opened/created, false otherwise
* @throws {@link SQLException] if an error ocorred
*/
public boolean open() throws SQLException {
try{
this.dbHelper = new DbHelper(this.context);
this.sqlDatabase = this.dbHelper.getWritableDatabase();
return this.sqlDatabase.isOpen();
}catch (SQLException e) {
throw e;
}
}
/**
* Close the database connection
* @return {@link Boolean} true if the connection was terminated, false otherwise
*/
public boolean close() {
this.dbHelper.close();
return !this.sqlDatabase.isOpen();
}
/**
* Check if the database is opened
*
* @return {@link Boolean} true if it was, false otherwise
*/
public boolean isOpen(){
return this.sqlDatabase.isOpen();
}
/**
* Check if the database was created
*
* @return {@link Boolean} true if it was, false otherwise
*/
public boolean databaseCreated(){
return this.dbHelper.databaseCreated();
}
/**
* Insert a new row on the table
*
* @param username {@link String} with the username
* @param fullname {@link String} with the fullname
* @param email {@link String} with the email
* @return {@link Long} with the row id or ROW_INSERT_FAILED (bellow 0 value) on error
*/
public long insertRow(String feed_guid, String feed_description) {
try{
// Prepare the values
ContentValues values = new ContentValues();
//values.put(KEY_ID, id);
values.put(KEY_FEED_GUID, feed_guid);
values.put(KEY_FEED_TEXT, feed_description);
// Try to insert the row
return this.sqlDatabase.insert(TABLE_NAME, null, values);
}catch (Exception e) {
Log.e(LOG_TAG, "An error occurred while inserting the row: "+e.toString(), e);
}
return ROW_INSERT_FAILED;
}
/**
* The search method
* Uses the full text search 3 virtual table and the MATCH function from SQLite to search for data
* @see http://www.sqlite.org/fts3.html to know more about the syntax
* @param search {@link String} with the search expression
* @return {@link LinkedList} with the {@link String} search results
*/
public HashSet<String> search(String search) {
HashSet<String> results = new HashSet<String>();
Cursor cursor = null;
try{
cursor = this.sqlDatabase.query(true, TABLE_NAME, new String[] { KEY_FEED_GUID }, KEY_FEED_TEXT + " MATCH ?", new String[] { "'" + search.trim() + "'" }, null, null, null, null);
if(cursor!=null && cursor.getCount()>0 && cursor.moveToFirst()){
int idColumnGUID = cursor.getColumnIndex(KEY_FEED_GUID);
do{
results.add(
new String(
cursor.getString(idColumnGUID)
)
);
}while(cursor.moveToNext());
}
}catch(Exception e){
Log.e(LOG_TAG, "An error occurred while searching for "+search+": "+e.toString(), e);
}finally{
if(cursor!=null && !cursor.isClosed()){
cursor.close();
close();
}
}
return results;
}
}