package com.androsz.flatnote.db;
import java.util.ArrayList;
import java.util.HashMap;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.graphics.Color;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;
import com.androsz.flatnote.app.widget.NotebookButton;
public final class Notebooks {
public static final String AUTHORITY = "com.androsz.flatnote.db.Notebooks";
private final static class Helper extends SQLiteOpenHelper {
private static final String DB_NAME = "notebooks.db";
private static final int DB_VERSION = 1;
public Helper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
final StringBuilder sb = new StringBuilder();
sb.append("CREATE TABLE ");
sb.append(MainTable.TABLE_NAME);
sb.append(" (");
sb.append(MainTable._ID);
sb.append("INTEGER PRIMARY KEY,");
sb.append(MainTable.KEY_NAME);
sb.append(" TEXT,");
sb.append(MainTable.KEY_COLOR);
sb.append(" INTEGER);");
db.execSQL(sb.toString());
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + MainTable.TABLE_NAME);
onCreate(db);
}
}
/**
* Definition of the contract for the main table of our provider.
*/
public static final class MainTable implements BaseColumns {
// This class cannot be instantiated
private MainTable() {
}
/**
* The table name offered by this provider
*/
public static final String TABLE_NAME = "notebooks";
/**
* The content:// style URL for this table
*/
public static final Uri CONTENT_URI = Uri.parse("content://"
+ AUTHORITY + "/" + TABLE_NAME);
/**
* The content URI base for a single row of data. Callers must append a
* numeric row id to this Uri to retrieve a row
*/
public static final Uri CONTENT_ID_URI_BASE = Uri.parse("content://"
+ AUTHORITY + "/" + TABLE_NAME + "/");
/**
* The MIME type of {@link #CONTENT_URI}.
*/
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.androsz.flatnote.notebooks";
/**
* The MIME type of a {@link #CONTENT_URI} sub-directory of a single
* row.
*/
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.androsz.flatnote.notebooks";
/**
* Keys for the columns names
*/
public static final String KEY_NAME = "KEY_NAME";
private static final String KEY_COLOR = "KEY_COLOR";
/**
* The default sort order for this table
*/
public static final String DEFAULT_SORT_ORDER = KEY_NAME
+ " COLLATE LOCALIZED ASC";
public static final String[] COLUMN_PROJECTION = new String[] { KEY_NAME,
KEY_COLOR };
}
/**
* A very simple implementation of a content provider.
*/
public static class Provider extends ContentProvider {
// A projection map used to select columns from the database
private final HashMap<String, String> projectionMap;
// Uri matcher to decode incoming URIs.
private final UriMatcher uriMatcher;
// The incoming URI matches the main table URI pattern
private static final int MAIN = 1;
// The incoming URI matches the main table row ID URI pattern
private static final int MAIN_ID = 2;
// Handle to a new DatabaseHelper.
private Helper helper;
/**
* Global provider initialization.
*/
public Provider() {
// Create and initialize URI matcher.
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, MainTable.TABLE_NAME, MAIN);
uriMatcher.addURI(AUTHORITY, MainTable.TABLE_NAME + "/#", MAIN_ID);
// Create and initialize projection map for all columns. This is
// simply an identity mapping.
projectionMap = new HashMap<String, String>();
projectionMap.put(MainTable._ID, MainTable._ID);
projectionMap.put(MainTable.KEY_NAME, MainTable.KEY_NAME);
projectionMap.put(MainTable.KEY_COLOR, MainTable.KEY_COLOR);
}
/**
* Perform provider creation.
*/
@Override
public boolean onCreate() {
helper = new Helper(getContext());
// Assumes that any failures will be reported by a thrown exception.
return true;
}
/**
* Handle incoming queries.
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// Constructs a new query builder and sets its table name
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(MainTable.TABLE_NAME);
switch (uriMatcher.match(uri)) {
case MAIN:
// If the incoming URI is for main table.
qb.setProjectionMap(projectionMap);
break;
case MAIN_ID:
// The incoming URI is for a single row.
qb.setProjectionMap(projectionMap);
qb.appendWhere(MainTable._ID + "=?");
selectionArgs = DatabaseUtils.appendSelectionArgs(
selectionArgs,
new String[] { uri.getLastPathSegment() });
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
if (TextUtils.isEmpty(sortOrder)) {
sortOrder = MainTable.DEFAULT_SORT_ORDER;
}
SQLiteDatabase db = helper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs,
null /* no group */, null /* no filter */, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
/**
* Return the MIME type for an known URI in the provider.
*/
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case MAIN:
return MainTable.CONTENT_TYPE;
case MAIN_ID:
return MainTable.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
/**
* Handler inserting new data.
*/
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
if (uriMatcher.match(uri) != MAIN) {
// Can only insert into to main URI.
throw new IllegalArgumentException("Unknown URI " + uri);
}
ContentValues values;
if (initialValues != null) {
values = new ContentValues(initialValues);
} else {
values = new ContentValues();
}
if (!values.containsKey(MainTable.KEY_NAME)) {
values.put(MainTable.KEY_NAME, "");
}
if (!values.containsKey(MainTable.KEY_COLOR)) {
values.put(MainTable.KEY_COLOR, Color.CYAN);
}
SQLiteDatabase db = helper.getWritableDatabase();
long rowId = db.insert(MainTable.TABLE_NAME, null, values);
// If the insert succeeded, the row ID exists.
if (rowId > 0) {
Uri noteUri = ContentUris.withAppendedId(
MainTable.CONTENT_ID_URI_BASE, rowId);
notifyChange(noteUri);
return noteUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
/**
* Handle deleting data.
*/
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
String finalWhere;
int count;
switch (uriMatcher.match(uri)) {
case MAIN:
// If URI is main table, delete uses incoming where clause and
// args.
count = db.delete(MainTable.TABLE_NAME, where, whereArgs);
break;
// If the incoming URI matches a single note ID, does the delete
// based on the
// incoming data, but modifies the where clause to restrict it to
// the
// particular note ID.
case MAIN_ID:
// If URI is for a particular row ID, delete is based on
// incoming
// data but modified to restrict to the given ID.
finalWhere = DatabaseUtils.concatenateWhere(MainTable._ID
+ " = " + ContentUris.parseId(uri), where);
count = db.delete(MainTable.TABLE_NAME, finalWhere, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
notifyChange(uri);
return count;
}
private void notifyChange(Uri uri) {
getContext().getContentResolver().notifyChange(uri, null);
}
/**
* Handle updating data.
*/
@Override
public int update(Uri uri, ContentValues values, String where,
String[] whereArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
int count;
String finalWhere;
switch (uriMatcher.match(uri)) {
case MAIN:
// If URI is main table, update uses incoming where clause and
// args.
count = db.update(MainTable.TABLE_NAME, values, where,
whereArgs);
break;
case MAIN_ID:
// If URI is for a particular row ID, update is based on
// incoming
// data but modified to restrict to the given ID.
finalWhere = DatabaseUtils.concatenateWhere(MainTable._ID
+ " = " + ContentUris.parseId(uri), where);
count = db.update(MainTable.TABLE_NAME, values, finalWhere,
whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
notifyChange(uri);
return count;
}
}
/**
* This class cannot be instantiated
*/
Notebooks(){}
public static Uri createNotebook(Context context, String name, int color) {
final ContentResolver contentResolver = context.getContentResolver();
final ContentValues values = new ContentValues();
values.put(MainTable.KEY_NAME, name);
values.put(MainTable.KEY_COLOR, color);
final Uri uri = contentResolver.insert(MainTable.CONTENT_URI, values);
return uri;
}
public static int updateNotebook(final Context context,String oldName, String newName, int newColor) {
final ContentResolver contentResolver = context.getContentResolver();
final ContentValues values = new ContentValues();
values.put(MainTable.KEY_NAME, newName);
values.put(MainTable.KEY_COLOR, newColor);
int numRowsUpdated = contentResolver.update(MainTable.CONTENT_URI, values,
MainTable.KEY_NAME + "='" + oldName + "'", null);
return numRowsUpdated;
}
public static int deleteNotebook(final Context context,
CharSequence notebookName) {
final ContentResolver contentResolver = context.getContentResolver();
final int numRowsDeleted = contentResolver.delete(
MainTable.CONTENT_URI, MainTable.KEY_NAME + "='" + notebookName
+ "'", null);
return numRowsDeleted;
}
public static ArrayList<NotebookButton> getNotebooksFromCursor(Context context,
Cursor c) {
ArrayList<NotebookButton> notebooks = new ArrayList<NotebookButton>();
if (c != null && c.moveToFirst()) {
do {
notebooks.add(new NotebookButton(context, c.getString(c.getColumnIndex(MainTable.KEY_NAME)), c
.getInt(c.getColumnIndex(MainTable.KEY_COLOR))));
} while (c.moveToNext());
c.close();
}
return notebooks;
}
}