FileContentProvider.java 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824
  1. /* ownCloud Android client application
  2. * Copyright (C) 2011 Bartek Przybylski
  3. * Copyright (C) 2012-2013 ownCloud Inc.
  4. *
  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.
  8. *
  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.
  13. *
  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/>.
  16. *
  17. */
  18. package com.owncloud.android.providers;
  19. import java.util.ArrayList;
  20. import java.util.HashMap;
  21. import com.owncloud.android.R;
  22. import com.owncloud.android.db.ProviderMeta;
  23. import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
  24. import com.owncloud.android.lib.common.utils.Log_OC;
  25. import com.owncloud.android.lib.resources.shares.ShareType;
  26. import android.content.ContentProvider;
  27. import android.content.ContentProviderOperation;
  28. import android.content.ContentProviderResult;
  29. import android.content.ContentUris;
  30. import android.content.ContentValues;
  31. import android.content.Context;
  32. import android.content.OperationApplicationException;
  33. import android.content.UriMatcher;
  34. import android.database.Cursor;
  35. import android.database.SQLException;
  36. import android.database.sqlite.SQLiteDatabase;
  37. import android.database.sqlite.SQLiteOpenHelper;
  38. import android.database.sqlite.SQLiteQueryBuilder;
  39. import android.net.Uri;
  40. import android.text.TextUtils;
  41. /**
  42. * The ContentProvider for the ownCloud App.
  43. *
  44. * @author Bartek Przybylski
  45. * @author David A. Velasco
  46. *
  47. */
  48. public class FileContentProvider extends ContentProvider {
  49. private DataBaseHelper mDbHelper;
  50. // Projection for filelist table
  51. private static HashMap<String, String> mFileProjectionMap;
  52. static {
  53. mFileProjectionMap = new HashMap<String, String>();
  54. mFileProjectionMap.put(ProviderTableMeta._ID, ProviderTableMeta._ID);
  55. mFileProjectionMap.put(ProviderTableMeta.FILE_PARENT,
  56. ProviderTableMeta.FILE_PARENT);
  57. mFileProjectionMap.put(ProviderTableMeta.FILE_PATH,
  58. ProviderTableMeta.FILE_PATH);
  59. mFileProjectionMap.put(ProviderTableMeta.FILE_NAME,
  60. ProviderTableMeta.FILE_NAME);
  61. mFileProjectionMap.put(ProviderTableMeta.FILE_CREATION,
  62. ProviderTableMeta.FILE_CREATION);
  63. mFileProjectionMap.put(ProviderTableMeta.FILE_MODIFIED,
  64. ProviderTableMeta.FILE_MODIFIED);
  65. mFileProjectionMap.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
  66. ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA);
  67. mFileProjectionMap.put(ProviderTableMeta.FILE_CONTENT_LENGTH,
  68. ProviderTableMeta.FILE_CONTENT_LENGTH);
  69. mFileProjectionMap.put(ProviderTableMeta.FILE_CONTENT_TYPE,
  70. ProviderTableMeta.FILE_CONTENT_TYPE);
  71. mFileProjectionMap.put(ProviderTableMeta.FILE_STORAGE_PATH,
  72. ProviderTableMeta.FILE_STORAGE_PATH);
  73. mFileProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE,
  74. ProviderTableMeta.FILE_LAST_SYNC_DATE);
  75. mFileProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA,
  76. ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA);
  77. mFileProjectionMap.put(ProviderTableMeta.FILE_KEEP_IN_SYNC,
  78. ProviderTableMeta.FILE_KEEP_IN_SYNC);
  79. mFileProjectionMap.put(ProviderTableMeta.FILE_ACCOUNT_OWNER,
  80. ProviderTableMeta.FILE_ACCOUNT_OWNER);
  81. mFileProjectionMap.put(ProviderTableMeta.FILE_ETAG,
  82. ProviderTableMeta.FILE_ETAG);
  83. mFileProjectionMap.put(ProviderTableMeta.FILE_SHARE_BY_LINK,
  84. ProviderTableMeta.FILE_SHARE_BY_LINK);
  85. mFileProjectionMap.put(ProviderTableMeta.FILE_PUBLIC_LINK,
  86. ProviderTableMeta.FILE_PUBLIC_LINK);
  87. mFileProjectionMap.put(ProviderTableMeta.FILE_PERMISSIONS,
  88. ProviderTableMeta.FILE_PERMISSIONS);
  89. mFileProjectionMap.put(ProviderTableMeta.FILE_REMOTE_ID,
  90. ProviderTableMeta.FILE_REMOTE_ID);
  91. mFileProjectionMap.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL,
  92. ProviderTableMeta.FILE_UPDATE_THUMBNAIL);
  93. mFileProjectionMap.put(ProviderTableMeta.FILE_IS_DOWNLOADING,
  94. ProviderTableMeta.FILE_IS_DOWNLOADING);
  95. }
  96. private static final int SINGLE_FILE = 1;
  97. private static final int DIRECTORY = 2;
  98. private static final int ROOT_DIRECTORY = 3;
  99. private static final int SHARES = 4;
  100. private static final String TAG = FileContentProvider.class.getSimpleName();
  101. // Projection for ocshares table
  102. private static HashMap<String, String> mOCSharesProjectionMap;
  103. static {
  104. mOCSharesProjectionMap = new HashMap<String, String>();
  105. mOCSharesProjectionMap.put(ProviderTableMeta._ID, ProviderTableMeta._ID);
  106. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_FILE_SOURCE,
  107. ProviderTableMeta.OCSHARES_FILE_SOURCE);
  108. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_ITEM_SOURCE,
  109. ProviderTableMeta.OCSHARES_ITEM_SOURCE);
  110. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_SHARE_TYPE,
  111. ProviderTableMeta.OCSHARES_SHARE_TYPE);
  112. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_SHARE_WITH,
  113. ProviderTableMeta.OCSHARES_SHARE_WITH);
  114. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_PATH,
  115. ProviderTableMeta.OCSHARES_PATH);
  116. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_PERMISSIONS,
  117. ProviderTableMeta.OCSHARES_PERMISSIONS);
  118. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_SHARED_DATE,
  119. ProviderTableMeta.OCSHARES_SHARED_DATE);
  120. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_EXPIRATION_DATE,
  121. ProviderTableMeta.OCSHARES_EXPIRATION_DATE);
  122. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_TOKEN,
  123. ProviderTableMeta.OCSHARES_TOKEN);
  124. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME,
  125. ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME);
  126. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY,
  127. ProviderTableMeta.OCSHARES_IS_DIRECTORY);
  128. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_USER_ID,
  129. ProviderTableMeta.OCSHARES_USER_ID);
  130. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED,
  131. ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED);
  132. mOCSharesProjectionMap.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER,
  133. ProviderTableMeta.OCSHARES_ACCOUNT_OWNER);
  134. }
  135. private UriMatcher mUriMatcher;
  136. @Override
  137. public int delete(Uri uri, String where, String[] whereArgs) {
  138. //Log_OC.d(TAG, "Deleting " + uri + " at provider " + this);
  139. int count = 0;
  140. SQLiteDatabase db = mDbHelper.getWritableDatabase();
  141. db.beginTransaction();
  142. try {
  143. count = delete(db, uri, where, whereArgs);
  144. db.setTransactionSuccessful();
  145. } finally {
  146. db.endTransaction();
  147. }
  148. getContext().getContentResolver().notifyChange(uri, null);
  149. return count;
  150. }
  151. private int delete(SQLiteDatabase db, Uri uri, String where, String[] whereArgs) {
  152. int count = 0;
  153. switch (mUriMatcher.match(uri)) {
  154. case SINGLE_FILE:
  155. Cursor c = query(db, uri, null, where, whereArgs, null);
  156. String remoteId = "";
  157. if (c != null && c.moveToFirst()) {
  158. remoteId = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_REMOTE_ID));
  159. //ThumbnailsCacheManager.removeFileFromCache(remoteId);
  160. }
  161. Log_OC.d(TAG, "Removing FILE " + remoteId);
  162. count = db.delete(ProviderTableMeta.FILE_TABLE_NAME,
  163. ProviderTableMeta._ID
  164. + "="
  165. + uri.getPathSegments().get(1)
  166. + (!TextUtils.isEmpty(where) ? " AND (" + where
  167. + ")" : ""), whereArgs);
  168. /* just for log
  169. if (c!=null) {
  170. c.close();
  171. }
  172. */
  173. break;
  174. case DIRECTORY:
  175. // deletion of folder is recursive
  176. /*
  177. Uri folderUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, Long.parseLong(uri.getPathSegments().get(1)));
  178. Cursor folder = query(db, folderUri, null, null, null, null);
  179. String folderName = "(unknown)";
  180. if (folder != null && folder.moveToFirst()) {
  181. folderName = folder.getString(folder.getColumnIndex(ProviderTableMeta.FILE_PATH));
  182. }
  183. */
  184. Cursor children = query(uri, null, null, null, null);
  185. if (children != null && children.moveToFirst()) {
  186. long childId;
  187. boolean isDir;
  188. //String remotePath;
  189. while (!children.isAfterLast()) {
  190. childId = children.getLong(children.getColumnIndex(ProviderTableMeta._ID));
  191. isDir = "DIR".equals(children.getString(
  192. children.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)
  193. ));
  194. //remotePath = children.getString(children.getColumnIndex(ProviderTableMeta.FILE_PATH));
  195. if (isDir) {
  196. count += delete(
  197. db,
  198. ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_DIR, childId),
  199. null,
  200. null
  201. );
  202. } else {
  203. count += delete(
  204. db,
  205. ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, childId),
  206. null,
  207. null
  208. );
  209. }
  210. children.moveToNext();
  211. }
  212. children.close();
  213. } /*else {
  214. Log_OC.d(TAG, "No child to remove in DIRECTORY " + folderName);
  215. }
  216. Log_OC.d(TAG, "Removing DIRECTORY " + folderName + " (or maybe not) ");
  217. */
  218. count += db.delete(ProviderTableMeta.FILE_TABLE_NAME,
  219. ProviderTableMeta._ID
  220. + "="
  221. + uri.getPathSegments().get(1)
  222. + (!TextUtils.isEmpty(where) ? " AND (" + where
  223. + ")" : ""), whereArgs);
  224. /* Just for log
  225. if (folder != null) {
  226. folder.close();
  227. }*/
  228. break;
  229. case ROOT_DIRECTORY:
  230. //Log_OC.d(TAG, "Removing ROOT!");
  231. count = db.delete(ProviderTableMeta.FILE_TABLE_NAME, where, whereArgs);
  232. break;
  233. case SHARES:
  234. count = db.delete(ProviderTableMeta.OCSHARES_TABLE_NAME, where, whereArgs);
  235. break;
  236. default:
  237. //Log_OC.e(TAG, "Unknown uri " + uri);
  238. throw new IllegalArgumentException("Unknown uri: " + uri.toString());
  239. }
  240. return count;
  241. }
  242. @Override
  243. public String getType(Uri uri) {
  244. switch (mUriMatcher.match(uri)) {
  245. case ROOT_DIRECTORY:
  246. return ProviderTableMeta.CONTENT_TYPE;
  247. case SINGLE_FILE:
  248. return ProviderTableMeta.CONTENT_TYPE_ITEM;
  249. default:
  250. throw new IllegalArgumentException("Unknown Uri id."
  251. + uri.toString());
  252. }
  253. }
  254. @Override
  255. public Uri insert(Uri uri, ContentValues values) {
  256. Uri newUri = null;
  257. SQLiteDatabase db = mDbHelper.getWritableDatabase();
  258. db.beginTransaction();
  259. try {
  260. newUri = insert(db, uri, values);
  261. db.setTransactionSuccessful();
  262. } finally {
  263. db.endTransaction();
  264. }
  265. getContext().getContentResolver().notifyChange(newUri, null);
  266. return newUri;
  267. }
  268. private Uri insert(SQLiteDatabase db, Uri uri, ContentValues values) {
  269. switch (mUriMatcher.match(uri)){
  270. case ROOT_DIRECTORY:
  271. case SINGLE_FILE:
  272. String remotePath = values.getAsString(ProviderTableMeta.FILE_PATH);
  273. String accountName = values.getAsString(ProviderTableMeta.FILE_ACCOUNT_OWNER);
  274. String[] projection = new String[] {
  275. ProviderTableMeta._ID, ProviderTableMeta.FILE_PATH,
  276. ProviderTableMeta.FILE_ACCOUNT_OWNER
  277. };
  278. String where = ProviderTableMeta.FILE_PATH + "=? AND " +
  279. ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?";
  280. String[] whereArgs = new String[] {remotePath, accountName};
  281. Cursor doubleCheck = query(db, uri, projection, where, whereArgs, null);
  282. // ugly patch; serious refactorization is needed to reduce work in
  283. // FileDataStorageManager and bring it to FileContentProvider
  284. if (doubleCheck == null || !doubleCheck.moveToFirst()) {
  285. long rowId = db.insert(ProviderTableMeta.FILE_TABLE_NAME, null, values);
  286. if (rowId > 0) {
  287. Uri insertedFileUri =
  288. ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, rowId);
  289. return insertedFileUri;
  290. } else {
  291. throw new SQLException("ERROR " + uri);
  292. }
  293. } else {
  294. // file is already inserted; race condition, let's avoid a duplicated entry
  295. Uri insertedFileUri = ContentUris.withAppendedId(
  296. ProviderTableMeta.CONTENT_URI_FILE,
  297. doubleCheck.getLong(doubleCheck.getColumnIndex(ProviderTableMeta._ID))
  298. );
  299. doubleCheck.close();
  300. return insertedFileUri;
  301. }
  302. case SHARES:
  303. String path = values.getAsString(ProviderTableMeta.OCSHARES_PATH);
  304. String accountNameShare= values.getAsString(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER);
  305. String[] projectionShare = new String[] {
  306. ProviderTableMeta._ID, ProviderTableMeta.OCSHARES_PATH,
  307. ProviderTableMeta.OCSHARES_ACCOUNT_OWNER
  308. };
  309. String whereShare = ProviderTableMeta.OCSHARES_PATH + "=? AND " +
  310. ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
  311. String[] whereArgsShare = new String[] {path, accountNameShare};
  312. Uri insertedShareUri = null;
  313. Cursor doubleCheckShare =
  314. query(db, uri, projectionShare, whereShare, whereArgsShare, null);
  315. // ugly patch; serious refactorization is needed to reduce work in
  316. // FileDataStorageManager and bring it to FileContentProvider
  317. if (doubleCheckShare == null || !doubleCheckShare.moveToFirst()) {
  318. long rowId = db.insert(ProviderTableMeta.OCSHARES_TABLE_NAME, null, values);
  319. if (rowId >0) {
  320. insertedShareUri =
  321. ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_SHARE, rowId);
  322. } else {
  323. throw new SQLException("ERROR " + uri);
  324. }
  325. } else {
  326. // file is already inserted; race condition, let's avoid a duplicated entry
  327. insertedShareUri = ContentUris.withAppendedId(
  328. ProviderTableMeta.CONTENT_URI_SHARE,
  329. doubleCheckShare.getLong(
  330. doubleCheckShare.getColumnIndex(ProviderTableMeta._ID)
  331. )
  332. );
  333. doubleCheckShare.close();
  334. }
  335. updateFilesTableAccordingToShareInsertion(db, uri, values);
  336. return insertedShareUri;
  337. default:
  338. throw new IllegalArgumentException("Unknown uri id: " + uri);
  339. }
  340. }
  341. private void updateFilesTableAccordingToShareInsertion(
  342. SQLiteDatabase db, Uri uri, ContentValues shareValues
  343. ) {
  344. ContentValues fileValues = new ContentValues();
  345. fileValues.put(
  346. ProviderTableMeta.FILE_SHARE_BY_LINK,
  347. ShareType.PUBLIC_LINK.getValue() ==
  348. shareValues.getAsInteger(ProviderTableMeta.OCSHARES_SHARE_TYPE)? 1 : 0
  349. );
  350. String whereShare = ProviderTableMeta.FILE_PATH + "=? AND " +
  351. ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?";
  352. String[] whereArgsShare = new String[] {
  353. shareValues.getAsString(ProviderTableMeta.OCSHARES_PATH),
  354. shareValues.getAsString(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER)
  355. };
  356. db.update(ProviderTableMeta.FILE_TABLE_NAME, fileValues, whereShare, whereArgsShare);
  357. }
  358. @Override
  359. public boolean onCreate() {
  360. mDbHelper = new DataBaseHelper(getContext());
  361. String authority = getContext().getResources().getString(R.string.authority);
  362. mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  363. mUriMatcher.addURI(authority, null, ROOT_DIRECTORY);
  364. mUriMatcher.addURI(authority, "file/", SINGLE_FILE);
  365. mUriMatcher.addURI(authority, "file/#", SINGLE_FILE);
  366. mUriMatcher.addURI(authority, "dir/", DIRECTORY);
  367. mUriMatcher.addURI(authority, "dir/#", DIRECTORY);
  368. mUriMatcher.addURI(authority, "shares/", SHARES);
  369. mUriMatcher.addURI(authority, "shares/#", SHARES);
  370. return true;
  371. }
  372. @Override
  373. public Cursor query(
  374. Uri uri,
  375. String[] projection,
  376. String selection,
  377. String[] selectionArgs,
  378. String sortOrder
  379. ) {
  380. Cursor result = null;
  381. SQLiteDatabase db = mDbHelper.getReadableDatabase();
  382. db.beginTransaction();
  383. try {
  384. result = query(db, uri, projection, selection, selectionArgs, sortOrder);
  385. db.setTransactionSuccessful();
  386. } finally {
  387. db.endTransaction();
  388. }
  389. return result;
  390. }
  391. private Cursor query(
  392. SQLiteDatabase db,
  393. Uri uri,
  394. String[] projection,
  395. String selection,
  396. String[] selectionArgs,
  397. String sortOrder
  398. ) {
  399. SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();
  400. sqlQuery.setTables(ProviderTableMeta.FILE_TABLE_NAME);
  401. sqlQuery.setProjectionMap(mFileProjectionMap);
  402. switch (mUriMatcher.match(uri)) {
  403. case ROOT_DIRECTORY:
  404. break;
  405. case DIRECTORY:
  406. String folderId = uri.getPathSegments().get(1);
  407. sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="
  408. + folderId);
  409. break;
  410. case SINGLE_FILE:
  411. if (uri.getPathSegments().size() > 1) {
  412. sqlQuery.appendWhere(ProviderTableMeta._ID + "="
  413. + uri.getPathSegments().get(1));
  414. }
  415. break;
  416. case SHARES:
  417. sqlQuery.setTables(ProviderTableMeta.OCSHARES_TABLE_NAME);
  418. sqlQuery.setProjectionMap(mOCSharesProjectionMap);
  419. if (uri.getPathSegments().size() > 1) {
  420. sqlQuery.appendWhere(ProviderTableMeta._ID + "="
  421. + uri.getPathSegments().get(1));
  422. }
  423. break;
  424. default:
  425. throw new IllegalArgumentException("Unknown uri id: " + uri);
  426. }
  427. String order;
  428. if (TextUtils.isEmpty(sortOrder)) {
  429. if (mUriMatcher.match(uri) == SHARES) {
  430. order = ProviderTableMeta.OCSHARES_DEFAULT_SORT_ORDER;
  431. } else {
  432. order = ProviderTableMeta.FILE_DEFAULT_SORT_ORDER;
  433. }
  434. } else {
  435. order = sortOrder;
  436. }
  437. // DB case_sensitive
  438. db.execSQL("PRAGMA case_sensitive_like = true");
  439. Cursor c = sqlQuery.query(db, projection, selection, selectionArgs, null, null, order);
  440. c.setNotificationUri(getContext().getContentResolver(), uri);
  441. return c;
  442. }
  443. @Override
  444. public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
  445. int count = 0;
  446. SQLiteDatabase db = mDbHelper.getWritableDatabase();
  447. db.beginTransaction();
  448. try {
  449. count = update(db, uri, values, selection, selectionArgs);
  450. db.setTransactionSuccessful();
  451. } finally {
  452. db.endTransaction();
  453. }
  454. getContext().getContentResolver().notifyChange(uri, null);
  455. return count;
  456. }
  457. private int update(
  458. SQLiteDatabase db,
  459. Uri uri,
  460. ContentValues values,
  461. String selection,
  462. String[] selectionArgs
  463. ) {
  464. switch (mUriMatcher.match(uri)) {
  465. case DIRECTORY:
  466. return 0; //updateFolderSize(db, selectionArgs[0]);
  467. case SHARES:
  468. return db.update(
  469. ProviderTableMeta.OCSHARES_TABLE_NAME, values, selection, selectionArgs
  470. );
  471. default:
  472. return db.update(
  473. ProviderTableMeta.FILE_TABLE_NAME, values, selection, selectionArgs
  474. );
  475. }
  476. }
  477. /*
  478. private int updateFolderSize(SQLiteDatabase db, String folderId) {
  479. int count = 0;
  480. String [] whereArgs = new String[] { folderId };
  481. // read current size saved for the folder
  482. long folderSize = 0;
  483. long folderParentId = -1;
  484. Uri selectFolderUri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, folderId);
  485. String[] folderProjection = new String[] { ProviderTableMeta.FILE_CONTENT_LENGTH, ProviderTableMeta.FILE_PARENT};
  486. String folderWhere = ProviderTableMeta._ID + "=?";
  487. Cursor folderCursor = query(db, selectFolderUri, folderProjection, folderWhere, whereArgs, null);
  488. if (folderCursor != null && folderCursor.moveToFirst()) {
  489. folderSize = folderCursor.getLong(folderCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH));;
  490. folderParentId = folderCursor.getLong(folderCursor.getColumnIndex(ProviderTableMeta.FILE_PARENT));;
  491. }
  492. folderCursor.close();
  493. // read and sum sizes of children
  494. long childrenSize = 0;
  495. Uri selectChildrenUri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, folderId);
  496. String[] childrenProjection = new String[] { ProviderTableMeta.FILE_CONTENT_LENGTH, ProviderTableMeta.FILE_PARENT};
  497. String childrenWhere = ProviderTableMeta.FILE_PARENT + "=?";
  498. Cursor childrenCursor = query(db, selectChildrenUri, childrenProjection, childrenWhere, whereArgs, null);
  499. if (childrenCursor != null && childrenCursor.moveToFirst()) {
  500. while (!childrenCursor.isAfterLast()) {
  501. childrenSize += childrenCursor.getLong(childrenCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH));
  502. childrenCursor.moveToNext();
  503. }
  504. }
  505. childrenCursor.close();
  506. // update if needed
  507. if (folderSize != childrenSize) {
  508. Log_OC.d("FileContentProvider", "Updating " + folderSize + " to " + childrenSize);
  509. ContentValues cv = new ContentValues();
  510. cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, childrenSize);
  511. count = db.update(ProviderTableMeta.FILE_TABLE_NAME, cv, folderWhere, whereArgs);
  512. // propagate update until root
  513. if (folderParentId > FileDataStorageManager.ROOT_PARENT_ID) {
  514. Log_OC.d("FileContentProvider", "Propagating update to " + folderParentId);
  515. updateFolderSize(db, String.valueOf(folderParentId));
  516. } else {
  517. Log_OC.d("FileContentProvider", "NOT propagating to " + folderParentId);
  518. }
  519. } else {
  520. Log_OC.d("FileContentProvider", "NOT updating, sizes are " + folderSize + " and " + childrenSize);
  521. }
  522. return count;
  523. }
  524. */
  525. @Override
  526. public ContentProviderResult[] applyBatch (ArrayList<ContentProviderOperation> operations)
  527. throws OperationApplicationException {
  528. Log_OC.d("FileContentProvider", "applying batch in provider " + this +
  529. " (temporary: " + isTemporary() + ")" );
  530. ContentProviderResult[] results = new ContentProviderResult[operations.size()];
  531. int i=0;
  532. SQLiteDatabase db = mDbHelper.getWritableDatabase();
  533. db.beginTransaction(); // it's supposed that transactions can be nested
  534. try {
  535. for (ContentProviderOperation operation : operations) {
  536. results[i] = operation.apply(this, results, i);
  537. i++;
  538. }
  539. db.setTransactionSuccessful();
  540. } finally {
  541. db.endTransaction();
  542. }
  543. Log_OC.d("FileContentProvider", "applied batch in provider " + this);
  544. return results;
  545. }
  546. class DataBaseHelper extends SQLiteOpenHelper {
  547. public DataBaseHelper(Context context) {
  548. super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);
  549. }
  550. @Override
  551. public void onCreate(SQLiteDatabase db) {
  552. // files table
  553. Log_OC.i("SQL", "Entering in onCreate");
  554. db.execSQL("CREATE TABLE " + ProviderTableMeta.FILE_TABLE_NAME + "("
  555. + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
  556. + ProviderTableMeta.FILE_NAME + " TEXT, "
  557. + ProviderTableMeta.FILE_PATH + " TEXT, "
  558. + ProviderTableMeta.FILE_PARENT + " INTEGER, "
  559. + ProviderTableMeta.FILE_CREATION + " INTEGER, "
  560. + ProviderTableMeta.FILE_MODIFIED + " INTEGER, "
  561. + ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, "
  562. + ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, "
  563. + ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, "
  564. + ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT, "
  565. + ProviderTableMeta.FILE_LAST_SYNC_DATE + " INTEGER, "
  566. + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER, "
  567. + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " INTEGER, "
  568. + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " INTEGER, "
  569. + ProviderTableMeta.FILE_ETAG + " TEXT, "
  570. + ProviderTableMeta.FILE_SHARE_BY_LINK + " INTEGER, "
  571. + ProviderTableMeta.FILE_PUBLIC_LINK + " TEXT, "
  572. + ProviderTableMeta.FILE_PERMISSIONS + " TEXT null,"
  573. + ProviderTableMeta.FILE_REMOTE_ID + " TEXT null,"
  574. + ProviderTableMeta.FILE_UPDATE_THUMBNAIL + " INTEGER," //boolean
  575. + ProviderTableMeta.FILE_IS_DOWNLOADING + " INTEGER);" //boolean
  576. );
  577. // Create table ocshares
  578. db.execSQL("CREATE TABLE " + ProviderTableMeta.OCSHARES_TABLE_NAME + "("
  579. + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
  580. + ProviderTableMeta.OCSHARES_FILE_SOURCE + " INTEGER, "
  581. + ProviderTableMeta.OCSHARES_ITEM_SOURCE + " INTEGER, "
  582. + ProviderTableMeta.OCSHARES_SHARE_TYPE + " INTEGER, "
  583. + ProviderTableMeta.OCSHARES_SHARE_WITH + " TEXT, "
  584. + ProviderTableMeta.OCSHARES_PATH + " TEXT, "
  585. + ProviderTableMeta.OCSHARES_PERMISSIONS+ " INTEGER, "
  586. + ProviderTableMeta.OCSHARES_SHARED_DATE + " INTEGER, "
  587. + ProviderTableMeta.OCSHARES_EXPIRATION_DATE + " INTEGER, "
  588. + ProviderTableMeta.OCSHARES_TOKEN + " TEXT, "
  589. + ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME + " TEXT, "
  590. + ProviderTableMeta.OCSHARES_IS_DIRECTORY + " INTEGER, " // boolean
  591. + ProviderTableMeta.OCSHARES_USER_ID + " INTEGER, "
  592. + ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + " INTEGER,"
  593. + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + " TEXT );" );
  594. }
  595. @Override
  596. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  597. Log_OC.i("SQL", "Entering in onUpgrade");
  598. boolean upgraded = false;
  599. if (oldVersion == 1 && newVersion >= 2) {
  600. Log_OC.i("SQL", "Entering in the #1 ADD in onUpgrade");
  601. db.execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  602. " ADD COLUMN " + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER " +
  603. " DEFAULT 0");
  604. upgraded = true;
  605. }
  606. if (oldVersion < 3 && newVersion >= 3) {
  607. Log_OC.i("SQL", "Entering in the #2 ADD in onUpgrade");
  608. db.beginTransaction();
  609. try {
  610. db.execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  611. " ADD COLUMN " + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA +
  612. " INTEGER " + " DEFAULT 0");
  613. // assume there are not local changes pending to upload
  614. db.execSQL("UPDATE " + ProviderTableMeta.FILE_TABLE_NAME +
  615. " SET " + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " = "
  616. + System.currentTimeMillis() +
  617. " WHERE " + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL");
  618. upgraded = true;
  619. db.setTransactionSuccessful();
  620. } finally {
  621. db.endTransaction();
  622. }
  623. }
  624. if (oldVersion < 4 && newVersion >= 4) {
  625. Log_OC.i("SQL", "Entering in the #3 ADD in onUpgrade");
  626. db.beginTransaction();
  627. try {
  628. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  629. " ADD COLUMN " + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA +
  630. " INTEGER " + " DEFAULT 0");
  631. db.execSQL("UPDATE " + ProviderTableMeta.FILE_TABLE_NAME +
  632. " SET " + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " = " +
  633. ProviderTableMeta.FILE_MODIFIED +
  634. " WHERE " + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL");
  635. upgraded = true;
  636. db.setTransactionSuccessful();
  637. } finally {
  638. db.endTransaction();
  639. }
  640. }
  641. if (!upgraded)
  642. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  643. ", newVersion == " + newVersion);
  644. if (oldVersion < 5 && newVersion >= 5) {
  645. Log_OC.i("SQL", "Entering in the #4 ADD in onUpgrade");
  646. db.beginTransaction();
  647. try {
  648. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  649. " ADD COLUMN " + ProviderTableMeta.FILE_ETAG + " TEXT " +
  650. " DEFAULT NULL");
  651. upgraded = true;
  652. db.setTransactionSuccessful();
  653. } finally {
  654. db.endTransaction();
  655. }
  656. }
  657. if (!upgraded)
  658. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  659. ", newVersion == " + newVersion);
  660. if (oldVersion < 6 && newVersion >= 6) {
  661. Log_OC.i("SQL", "Entering in the #5 ADD in onUpgrade");
  662. db.beginTransaction();
  663. try {
  664. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  665. " ADD COLUMN " + ProviderTableMeta.FILE_SHARE_BY_LINK + " INTEGER " +
  666. " DEFAULT 0");
  667. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  668. " ADD COLUMN " + ProviderTableMeta.FILE_PUBLIC_LINK + " TEXT " +
  669. " DEFAULT NULL");
  670. // Create table ocshares
  671. db.execSQL("CREATE TABLE " + ProviderTableMeta.OCSHARES_TABLE_NAME + "("
  672. + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
  673. + ProviderTableMeta.OCSHARES_FILE_SOURCE + " INTEGER, "
  674. + ProviderTableMeta.OCSHARES_ITEM_SOURCE + " INTEGER, "
  675. + ProviderTableMeta.OCSHARES_SHARE_TYPE + " INTEGER, "
  676. + ProviderTableMeta.OCSHARES_SHARE_WITH + " TEXT, "
  677. + ProviderTableMeta.OCSHARES_PATH + " TEXT, "
  678. + ProviderTableMeta.OCSHARES_PERMISSIONS+ " INTEGER, "
  679. + ProviderTableMeta.OCSHARES_SHARED_DATE + " INTEGER, "
  680. + ProviderTableMeta.OCSHARES_EXPIRATION_DATE + " INTEGER, "
  681. + ProviderTableMeta.OCSHARES_TOKEN + " TEXT, "
  682. + ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME + " TEXT, "
  683. + ProviderTableMeta.OCSHARES_IS_DIRECTORY + " INTEGER, " // boolean
  684. + ProviderTableMeta.OCSHARES_USER_ID + " INTEGER, "
  685. + ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + " INTEGER,"
  686. + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + " TEXT );" );
  687. upgraded = true;
  688. db.setTransactionSuccessful();
  689. } finally {
  690. db.endTransaction();
  691. }
  692. }
  693. if (!upgraded)
  694. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  695. ", newVersion == " + newVersion);
  696. if (oldVersion < 7 && newVersion >= 7) {
  697. Log_OC.i("SQL", "Entering in the #7 ADD in onUpgrade");
  698. db.beginTransaction();
  699. try {
  700. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  701. " ADD COLUMN " + ProviderTableMeta.FILE_PERMISSIONS + " TEXT " +
  702. " DEFAULT NULL");
  703. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  704. " ADD COLUMN " + ProviderTableMeta.FILE_REMOTE_ID + " TEXT " +
  705. " DEFAULT NULL");
  706. upgraded = true;
  707. db.setTransactionSuccessful();
  708. } finally {
  709. db.endTransaction();
  710. }
  711. }
  712. if (!upgraded)
  713. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  714. ", newVersion == " + newVersion);
  715. if (oldVersion < 8 && newVersion >= 8) {
  716. Log_OC.i("SQL", "Entering in the #8 ADD in onUpgrade");
  717. db.beginTransaction();
  718. try {
  719. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  720. " ADD COLUMN " + ProviderTableMeta.FILE_UPDATE_THUMBNAIL + " INTEGER " +
  721. " DEFAULT 0");
  722. upgraded = true;
  723. db.setTransactionSuccessful();
  724. } finally {
  725. db.endTransaction();
  726. }
  727. }
  728. if (!upgraded)
  729. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  730. ", newVersion == " + newVersion);
  731. if (oldVersion < 9 && newVersion >= 9) {
  732. Log_OC.i("SQL", "Entering in the #9 ADD in onUpgrade");
  733. db.beginTransaction();
  734. try {
  735. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  736. " ADD COLUMN " + ProviderTableMeta.FILE_IS_DOWNLOADING + " INTEGER " +
  737. " DEFAULT 0");
  738. upgraded = true;
  739. db.setTransactionSuccessful();
  740. } finally {
  741. db.endTransaction();
  742. }
  743. }
  744. if (!upgraded)
  745. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  746. ", newVersion == " + newVersion);
  747. }
  748. }
  749. }