1 /* ownCloud Android client application 
   2  *   Copyright (C) 2011  Bartek Przybylski 
   3  *   Copyright (C) 2012-2013 ownCloud Inc. 
   5  *   This program is free software: you can redistribute it and/or modify 
   6  *   it under the terms of the GNU General Public License version 2, 
   7  *   as published by the Free Software Foundation. 
   9  *   This program is distributed in the hope that it will be useful, 
  10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
  11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  12  *   GNU General Public License for more details. 
  14  *   You should have received a copy of the GNU General Public License 
  15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  19 package com
.owncloud
.android
.providers
; 
  21 import java
.util
.HashMap
; 
  23 import com
.owncloud
.android
.Log_OC
; 
  24 import com
.owncloud
.android
.db
.ProviderMeta
; 
  25 import com
.owncloud
.android
.db
.ProviderMeta
.ProviderTableMeta
; 
  28 import android
.content
.ContentProvider
; 
  29 import android
.content
.ContentUris
; 
  30 import android
.content
.ContentValues
; 
  31 import android
.content
.Context
; 
  32 import android
.content
.UriMatcher
; 
  33 import android
.database
.Cursor
; 
  34 import android
.database
.SQLException
; 
  35 import android
.database
.sqlite
.SQLiteDatabase
; 
  36 import android
.database
.sqlite
.SQLiteOpenHelper
; 
  37 import android
.database
.sqlite
.SQLiteQueryBuilder
; 
  38 import android
.net
.Uri
; 
  39 import android
.text
.TextUtils
; 
  42  * The ContentProvider for the ownCloud App. 
  44  * @author Bartek Przybylski 
  47 public class FileContentProvider 
extends ContentProvider 
{ 
  49     private DataBaseHelper mDbHelper
; 
  51     private static HashMap
<String
, String
> mProjectionMap
; 
  53         mProjectionMap 
= new HashMap
<String
, String
>(); 
  54         mProjectionMap
.put(ProviderTableMeta
._ID
, ProviderTableMeta
._ID
); 
  55         mProjectionMap
.put(ProviderTableMeta
.FILE_PARENT
, 
  56                 ProviderTableMeta
.FILE_PARENT
); 
  57         mProjectionMap
.put(ProviderTableMeta
.FILE_PATH
, 
  58                 ProviderTableMeta
.FILE_PATH
); 
  59         mProjectionMap
.put(ProviderTableMeta
.FILE_NAME
, 
  60                 ProviderTableMeta
.FILE_NAME
); 
  61         mProjectionMap
.put(ProviderTableMeta
.FILE_CREATION
, 
  62                 ProviderTableMeta
.FILE_CREATION
); 
  63         mProjectionMap
.put(ProviderTableMeta
.FILE_MODIFIED
, 
  64                 ProviderTableMeta
.FILE_MODIFIED
); 
  65         mProjectionMap
.put(ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA
, 
  66                 ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA
); 
  67         mProjectionMap
.put(ProviderTableMeta
.FILE_CONTENT_LENGTH
, 
  68                 ProviderTableMeta
.FILE_CONTENT_LENGTH
); 
  69         mProjectionMap
.put(ProviderTableMeta
.FILE_CONTENT_TYPE
, 
  70                 ProviderTableMeta
.FILE_CONTENT_TYPE
); 
  71         mProjectionMap
.put(ProviderTableMeta
.FILE_STORAGE_PATH
, 
  72                 ProviderTableMeta
.FILE_STORAGE_PATH
); 
  73         mProjectionMap
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE
, 
  74                 ProviderTableMeta
.FILE_LAST_SYNC_DATE
); 
  75         mProjectionMap
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA
, 
  76                 ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA
); 
  77         mProjectionMap
.put(ProviderTableMeta
.FILE_KEEP_IN_SYNC
, 
  78                 ProviderTableMeta
.FILE_KEEP_IN_SYNC
); 
  79         mProjectionMap
.put(ProviderTableMeta
.FILE_ACCOUNT_OWNER
, 
  80                 ProviderTableMeta
.FILE_ACCOUNT_OWNER
); 
  83     private static final int SINGLE_FILE 
= 1; 
  84     private static final int DIRECTORY 
= 2; 
  85     private static final int ROOT_DIRECTORY 
= 3; 
  86     private static final UriMatcher mUriMatcher
; 
  88         mUriMatcher 
= new UriMatcher(UriMatcher
.NO_MATCH
); 
  89         mUriMatcher
.addURI(ProviderMeta
.AUTHORITY_FILES
, "/", ROOT_DIRECTORY
); 
  90         mUriMatcher
.addURI(ProviderMeta
.AUTHORITY_FILES
, "file/", SINGLE_FILE
); 
  91         mUriMatcher
.addURI(ProviderMeta
.AUTHORITY_FILES
, "file/#", SINGLE_FILE
); 
  92         mUriMatcher
.addURI(ProviderMeta
.AUTHORITY_FILES
, "dir/#", DIRECTORY
); 
  96     public int delete(Uri uri
, String where
, String
[] whereArgs
) { 
  97         SQLiteDatabase db 
= mDbHelper
.getWritableDatabase(); 
  99         switch (mUriMatcher
.match(uri
)) { 
 101             count 
= db
.delete(ProviderTableMeta
.DB_NAME
, 
 102                     ProviderTableMeta
._ID
 
 104                             + uri
.getPathSegments().get(1) 
 105                             + (!TextUtils
.isEmpty(where
) ? 
" AND (" + where
 
 106                                     + ")" : ""), whereArgs
); 
 109             count 
= db
.delete(ProviderTableMeta
.DB_NAME
, where
, whereArgs
); 
 112             throw new IllegalArgumentException("Unknown uri: " + uri
.toString()); 
 114         getContext().getContentResolver().notifyChange(uri
, null
); 
 119     public String 
getType(Uri uri
) { 
 120         switch (mUriMatcher
.match(uri
)) { 
 122             return ProviderTableMeta
.CONTENT_TYPE
; 
 124             return ProviderTableMeta
.CONTENT_TYPE_ITEM
; 
 126             throw new IllegalArgumentException("Unknown Uri id." 
 132     public Uri 
insert(Uri uri
, ContentValues values
) { 
 133         if (mUriMatcher
.match(uri
) != SINGLE_FILE 
&& 
 134             mUriMatcher
.match(uri
) != ROOT_DIRECTORY
) { 
 136             throw new IllegalArgumentException("Unknown uri id: " + uri
); 
 139         SQLiteDatabase db 
= mDbHelper
.getWritableDatabase(); 
 140         long rowId 
= db
.insert(ProviderTableMeta
.DB_NAME
, null
, values
); 
 142             Uri insertedFileUri 
= ContentUris
.withAppendedId( 
 143                     ProviderTableMeta
.CONTENT_URI_FILE
, rowId
); 
 144             getContext().getContentResolver().notifyChange(insertedFileUri
, 
 146             return insertedFileUri
; 
 148         throw new SQLException("ERROR " + uri
); 
 152     public boolean onCreate() { 
 153         mDbHelper 
= new DataBaseHelper(getContext()); 
 158     public Cursor 
query(Uri uri
, String
[] projection
, String selection
, 
 159             String
[] selectionArgs
, String sortOrder
) { 
 160         SQLiteQueryBuilder sqlQuery 
= new SQLiteQueryBuilder(); 
 162         sqlQuery
.setTables(ProviderTableMeta
.DB_NAME
); 
 163         sqlQuery
.setProjectionMap(mProjectionMap
); 
 165         switch (mUriMatcher
.match(uri
)) { 
 169             sqlQuery
.appendWhere(ProviderTableMeta
.FILE_PARENT 
+ "=" 
 170                     + uri
.getPathSegments().get(1)); 
 173             if (uri
.getPathSegments().size() > 1) { 
 174                 sqlQuery
.appendWhere(ProviderTableMeta
._ID 
+ "=" 
 175                         + uri
.getPathSegments().get(1)); 
 179             throw new IllegalArgumentException("Unknown uri id: " + uri
); 
 183         if (TextUtils
.isEmpty(sortOrder
)) { 
 184             order 
= ProviderTableMeta
.DEFAULT_SORT_ORDER
; 
 189         SQLiteDatabase db 
= mDbHelper
.getReadableDatabase(); 
 190         Cursor c 
= sqlQuery
.query(db
, projection
, selection
, selectionArgs
, 
 193         c
.setNotificationUri(getContext().getContentResolver(), uri
); 
 199     public int update(Uri uri
, ContentValues values
, String selection
, 
 200             String
[] selectionArgs
) { 
 201         return mDbHelper
.getWritableDatabase().update( 
 202                 ProviderTableMeta
.DB_NAME
, values
, selection
, selectionArgs
); 
 205     class DataBaseHelper 
extends SQLiteOpenHelper 
{ 
 207         public DataBaseHelper(Context context
) { 
 208             super(context
, ProviderMeta
.DB_NAME
, null
, ProviderMeta
.DB_VERSION
); 
 213         public void onCreate(SQLiteDatabase db
) { 
 215             Log_OC
.i("SQL", "Entering in onCreate"); 
 216             db
.execSQL("CREATE TABLE " + ProviderTableMeta
.DB_NAME 
+ "(" 
 217                     + ProviderTableMeta
._ID 
+ " INTEGER PRIMARY KEY, " 
 218                     + ProviderTableMeta
.FILE_NAME 
+ " TEXT, " 
 219                     + ProviderTableMeta
.FILE_PATH 
+ " TEXT, " 
 220                     + ProviderTableMeta
.FILE_PARENT 
+ " INTEGER, " 
 221                     + ProviderTableMeta
.FILE_CREATION 
+ " INTEGER, " 
 222                     + ProviderTableMeta
.FILE_MODIFIED 
+ " INTEGER, " 
 223                     + ProviderTableMeta
.FILE_CONTENT_TYPE 
+ " TEXT, " 
 224                     + ProviderTableMeta
.FILE_CONTENT_LENGTH 
+ " INTEGER, " 
 225                     + ProviderTableMeta
.FILE_STORAGE_PATH 
+ " TEXT, " 
 226                     + ProviderTableMeta
.FILE_ACCOUNT_OWNER 
+ " TEXT, " 
 227                     + ProviderTableMeta
.FILE_LAST_SYNC_DATE 
+ " INTEGER, " 
 228                     + ProviderTableMeta
.FILE_KEEP_IN_SYNC 
+ " INTEGER, " 
 229                     + ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA 
+ " INTEGER, " 
 230                     + ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA 
+ " INTEGER );" 
 235         public void onUpgrade(SQLiteDatabase db
, int oldVersion
, int newVersion
) { 
 236             Log_OC
.i("SQL", "Entering in onUpgrade"); 
 237             boolean upgraded 
= false
;  
 238             if (oldVersion 
== 1 && newVersion 
>= 2) { 
 239                 Log_OC
.i("SQL", "Entering in the #1 ADD in onUpgrade"); 
 240                 db
.execSQL("ALTER TABLE " + ProviderTableMeta
.DB_NAME 
+ 
 241                            " ADD COLUMN " + ProviderTableMeta
.FILE_KEEP_IN_SYNC  
+ " INTEGER " + 
 245             if (oldVersion 
< 3 && newVersion 
>= 3) { 
 246                 Log_OC
.i("SQL", "Entering in the #2 ADD in onUpgrade"); 
 247                 db
.beginTransaction(); 
 249                     db
.execSQL("ALTER TABLE " + ProviderTableMeta
.DB_NAME 
+ 
 250                                " ADD COLUMN " + ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA  
+ " INTEGER " + 
 253                     // assume there are not local changes pending to upload 
 254                     db
.execSQL("UPDATE " + ProviderTableMeta
.DB_NAME 
+  
 255                             " SET " + ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA 
+ " = " + System
.currentTimeMillis() +  
 256                             " WHERE " + ProviderTableMeta
.FILE_STORAGE_PATH 
+ " IS NOT NULL"); 
 259                     db
.setTransactionSuccessful(); 
 264             if (oldVersion 
< 4 && newVersion 
>= 4) { 
 265                 Log_OC
.i("SQL", "Entering in the #3 ADD in onUpgrade"); 
 266                 db
.beginTransaction(); 
 268                     db 
.execSQL("ALTER TABLE " + ProviderTableMeta
.DB_NAME 
+ 
 269                            " ADD COLUMN " + ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA  
+ " INTEGER " + 
 272                     db
.execSQL("UPDATE " + ProviderTableMeta
.DB_NAME 
+  
 273                            " SET " + ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA 
+ " = " + ProviderTableMeta
.FILE_MODIFIED 
+  
 274                            " WHERE " + ProviderTableMeta
.FILE_STORAGE_PATH 
+ " IS NOT NULL"); 
 277                     db
.setTransactionSuccessful(); 
 283                 Log_OC
.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion 
+ ", newVersion == " + newVersion
);