/* ownCloud Android client application
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
package com.owncloud.android.providers;
import java.util.HashMap;
import com.owncloud.android.Log_OC;
import com.owncloud.android.R;
import com.owncloud.android.db.ProviderMeta;
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
/**
* The ContentProvider for the ownCloud App.
*
* @author Bartek Przybylski
*
*/
public class FileContentProvider extends ContentProvider {
private DataBaseHelper mDbHelper;
private static HashMap mProjectionMap;
static {
mProjectionMap = new HashMap();
mProjectionMap.put(ProviderTableMeta._ID, ProviderTableMeta._ID);
mProjectionMap.put(ProviderTableMeta.FILE_PARENT,
ProviderTableMeta.FILE_PARENT);
mProjectionMap.put(ProviderTableMeta.FILE_PATH,
ProviderTableMeta.FILE_PATH);
mProjectionMap.put(ProviderTableMeta.FILE_NAME,
ProviderTableMeta.FILE_NAME);
mProjectionMap.put(ProviderTableMeta.FILE_CREATION,
ProviderTableMeta.FILE_CREATION);
mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED,
ProviderTableMeta.FILE_MODIFIED);
mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA);
mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_LENGTH,
ProviderTableMeta.FILE_CONTENT_LENGTH);
mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_TYPE,
ProviderTableMeta.FILE_CONTENT_TYPE);
mProjectionMap.put(ProviderTableMeta.FILE_STORAGE_PATH,
ProviderTableMeta.FILE_STORAGE_PATH);
mProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE,
ProviderTableMeta.FILE_LAST_SYNC_DATE);
mProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA,
ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA);
mProjectionMap.put(ProviderTableMeta.FILE_KEEP_IN_SYNC,
ProviderTableMeta.FILE_KEEP_IN_SYNC);
mProjectionMap.put(ProviderTableMeta.FILE_ACCOUNT_OWNER,
ProviderTableMeta.FILE_ACCOUNT_OWNER);
}
private static final int SINGLE_FILE = 1;
private static final int DIRECTORY = 2;
private static final int ROOT_DIRECTORY = 3;
private UriMatcher mUriMatcher;
// static {
// mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, null, ROOT_DIRECTORY);
// mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/", SINGLE_FILE);
// mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/#", SINGLE_FILE);
// mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/#", DIRECTORY);
// }
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
int count = 0;
switch (mUriMatcher.match(uri)) {
case SINGLE_FILE:
count = db.delete(ProviderTableMeta.DB_NAME,
ProviderTableMeta._ID
+ "="
+ uri.getPathSegments().get(1)
+ (!TextUtils.isEmpty(where) ? " AND (" + where
+ ")" : ""), whereArgs);
break;
case ROOT_DIRECTORY:
count = db.delete(ProviderTableMeta.DB_NAME, where, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown uri: " + uri.toString());
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
switch (mUriMatcher.match(uri)) {
case ROOT_DIRECTORY:
return ProviderTableMeta.CONTENT_TYPE;
case SINGLE_FILE:
return ProviderTableMeta.CONTENT_TYPE_ITEM;
default:
throw new IllegalArgumentException("Unknown Uri id."
+ uri.toString());
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if (mUriMatcher.match(uri) != SINGLE_FILE &&
mUriMatcher.match(uri) != ROOT_DIRECTORY) {
throw new IllegalArgumentException("Unknown uri id: " + uri);
}
SQLiteDatabase db = mDbHelper.getWritableDatabase();
long rowId = db.insert(ProviderTableMeta.DB_NAME, null, values);
if (rowId > 0) {
Uri insertedFileUri = ContentUris.withAppendedId(
ProviderTableMeta.CONTENT_URI_FILE, rowId);
getContext().getContentResolver().notifyChange(insertedFileUri,
null);
return insertedFileUri;
}
throw new SQLException("ERROR " + uri);
}
@Override
public boolean onCreate() {
mDbHelper = new DataBaseHelper(getContext());
String authority = getContext().getResources().getString(R.string.authority);
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(authority, null, ROOT_DIRECTORY);
mUriMatcher.addURI(authority, "file/", SINGLE_FILE);
mUriMatcher.addURI(authority, "file/#", SINGLE_FILE);
mUriMatcher.addURI(authority, "dir/#", DIRECTORY);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();
sqlQuery.setTables(ProviderTableMeta.DB_NAME);
sqlQuery.setProjectionMap(mProjectionMap);
switch (mUriMatcher.match(uri)) {
case ROOT_DIRECTORY:
break;
case DIRECTORY:
sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="
+ uri.getPathSegments().get(1));
break;
case SINGLE_FILE:
if (uri.getPathSegments().size() > 1) {
sqlQuery.appendWhere(ProviderTableMeta._ID + "="
+ uri.getPathSegments().get(1));
}
break;
default:
throw new IllegalArgumentException("Unknown uri id: " + uri);
}
String order;
if (TextUtils.isEmpty(sortOrder)) {
order = ProviderTableMeta.DEFAULT_SORT_ORDER;
} else {
order = sortOrder;
}
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// DB case_sensitive
db.execSQL("PRAGMA case_sensitive_like = true");
Cursor c = sqlQuery.query(db, projection, selection, selectionArgs,
null, null, order);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return mDbHelper.getWritableDatabase().update(
ProviderTableMeta.DB_NAME, values, selection, selectionArgs);
}
class DataBaseHelper extends SQLiteOpenHelper {
public DataBaseHelper(Context context) {
super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// files table
Log_OC.i("SQL", "Entering in onCreate");
db.execSQL("CREATE TABLE " + ProviderTableMeta.DB_NAME + "("
+ ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
+ ProviderTableMeta.FILE_NAME + " TEXT, "
+ ProviderTableMeta.FILE_PATH + " TEXT, "
+ ProviderTableMeta.FILE_PARENT + " INTEGER, "
+ ProviderTableMeta.FILE_CREATION + " INTEGER, "
+ ProviderTableMeta.FILE_MODIFIED + " INTEGER, "
+ ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, "
+ ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, "
+ ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, "
+ ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT, "
+ ProviderTableMeta.FILE_LAST_SYNC_DATE + " INTEGER, "
+ ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER, "
+ ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " INTEGER, "
+ ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " INTEGER );"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log_OC.i("SQL", "Entering in onUpgrade");
boolean upgraded = false;
if (oldVersion == 1 && newVersion >= 2) {
Log_OC.i("SQL", "Entering in the #1 ADD in onUpgrade");
db.execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +
" ADD COLUMN " + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER " +
" DEFAULT 0");
upgraded = true;
}
if (oldVersion < 3 && newVersion >= 3) {
Log_OC.i("SQL", "Entering in the #2 ADD in onUpgrade");
db.beginTransaction();
try {
db.execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +
" ADD COLUMN " + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " INTEGER " +
" DEFAULT 0");
// assume there are not local changes pending to upload
db.execSQL("UPDATE " + ProviderTableMeta.DB_NAME +
" SET " + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " = " + System.currentTimeMillis() +
" WHERE " + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL");
upgraded = true;
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
if (oldVersion < 4 && newVersion >= 4) {
Log_OC.i("SQL", "Entering in the #3 ADD in onUpgrade");
db.beginTransaction();
try {
db .execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +
" ADD COLUMN " + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " INTEGER " +
" DEFAULT 0");
db.execSQL("UPDATE " + ProviderTableMeta.DB_NAME +
" SET " + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " = " + ProviderTableMeta.FILE_MODIFIED +
" WHERE " + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL");
upgraded = true;
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
if (!upgraded)
Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion + ", newVersion == " + newVersion);
}
}
}