/** * Copyright (c) 2013, Sana * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the Sana nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Sana BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.sana.android.db; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.text.TextUtils; import android.util.Log; /** * Implementation of a basic SQLiteOpenHelper class which performs common table * operations based on {@link android.net.Uri Uri} matching. * * @author Sana Development * */ public abstract class DatabaseOpenHelper extends SQLiteOpenHelper { public static final String TAG = DatabaseOpenHelper.class.getSimpleName(); /** * * @param context * @param name * @param matcher TODO */ public DatabaseOpenHelper(Context context, String name, int version){ super(context,name,null,version); } /* (non-Javadoc) * @see org.sana.android.db.InsertHelper#onInsert(android.content.ContentValues) @Override public ContentValues onInsert(ContentValues values) { SQLiteDatabase db = getWritableDatabase(); long id = db.insert(getTable(uri), null, values); Uri result = ContentUris.withAppendedId(uri, id); return result; } /* (non-Javadoc) * @see org.sana.android.db.UpdateHelper#onUpdate(android.content.ContentValues, java.lang.String, java.lang.String[]) * @Override public ContentValues onUpdate(ContentValues values) { SQLiteDatabase db = getWritableDatabase(); return db.update(table, values, selection, selectionArgs); } /* (non-Javadoc) * @see org.sana.android.db.FileHelper#openFile(long, java.lang.String) * @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { String path = null; Cursor c = null; // _ID based where String whereClause = DBUtils.getWhereClause(uri, mUriHelper.match(uri), null); String[] projection = new String[]{ getFileColumn(uri) }; try{ c = onQuery(null, projection, whereClause, null, null); if (c != null){ if(c.moveToFirst() && c.getCount() == 1) { // If there is not exactly one result, throw an appropriate // exception. path = c.getString(c.getColumnIndexOrThrow(getFileColumn(uri))); } else { throw new NullPointerException("No file entry for row: "+uri); } } else // Are we trying to open a null path if (TextUtils.isEmpty(path)) throw new NullPointerException("Null value in file column: " + getFileColumn(uri)); } finally { if (c!=null) c.close(); } // Open and return return ParcelFileDescriptor.open(new File(path), modeToMode(mode)); } /* (non-Javadoc) * @see org.sana.android.db.FileHelper#deleteFile(android.net.Uri) * @Override public int deleteFile(Uri uri) { String whereClause = DBUtils.getWhereClause(uri, mUriHelper.match(uri), null); return this.onDeleteRelated(uri, whereClause, null); } /* (non-Javadoc) * @see org.sana.android.db.DeleteHelper#onDelete(java.lang.String, java.lang.String[]) * @Override public int onDelete(Uri uri, String selection, String[] selectionArgs) { if(TextUtils.isEmpty(getFileColumn(uri))) onDeleteRelated(uri,selection, selectionArgs); SQLiteDatabase db = getWritableDatabase(); int count = db.delete(getTable(uri), selection, selectionArgs); return count; } public int onDeleteRelated(Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; String[] projection = new String[]{ getFileColumn(uri) }; int count = 0; try{ cursor = onQuery(null, projection, selection,selectionArgs, null); int column = cursor.getColumnIndex(getFileColumn(uri)); while(cursor.moveToNext()){ String path = (cursor.getString(column)); if(!TextUtils.isEmpty(path)){ count = (new File(path).delete())? count +1: count; } } } finally { if(cursor!=null) cursor.close(); } return count; } /* (non-Javadoc) * @see org.sana.android.db.QueryHelper#onQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String) * @Override public Cursor onQuery(String table, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = getReadableDatabase(); SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); qb.setTables(getTable(null)); return qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); } */ /** * * @param db * @param in */ public void onCreate(SQLiteDatabase db, InputStream in){ Log.d(TAG, "Attempting database creation."); try { readAndExecuteStream(db,in); Log.d(TAG, "Database creation complete"); } catch (IOException e) { Log.d(TAG, "Database creation failed."); throw new IllegalArgumentException("SQL table definition file " + "null or unreadable"); } } /** * * @param db * @param oldVersion * @param newVersion * @param in */ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion, InputStream in) { if(oldVersion < newVersion){ Log.d(TAG, "Attempting database upgrade."); try { readAndExecuteStream(db,in); Log.d(TAG, "Database upgrade complete"); } catch (IOException e) { Log.d(TAG, "Database upgrade failed."); throw new IllegalArgumentException("SQL upgrade definition file " + "null or unreadable"); } } } protected void readAndExecuteStream(SQLiteDatabase db, InputStream in) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String sql = reader.readLine(); while(!TextUtils.isEmpty(sql)){ Log.d(TAG, "Executing: "+ sql); db.execSQL(sql); sql = reader.readLine(); } } }