FileContentProvider.java 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089
  1. /**
  2. * ownCloud Android client application
  3. *
  4. * @author Bartek Przybylski
  5. * @author David A. Velasco
  6. * @author masensio
  7. * Copyright (C) 2011 Bartek Przybylski
  8. * Copyright (C) 2016 ownCloud Inc.
  9. *
  10. * This program is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2,
  12. * as published by the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. */
  23. package com.owncloud.android.providers;
  24. import android.accounts.Account;
  25. import android.accounts.AccountManager;
  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. import com.owncloud.android.MainApp;
  42. import com.owncloud.android.R;
  43. import com.owncloud.android.datamodel.OCFile;
  44. import com.owncloud.android.datamodel.UploadsStorageManager;
  45. import com.owncloud.android.db.ProviderMeta;
  46. import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
  47. import com.owncloud.android.lib.common.accounts.AccountUtils;
  48. import com.owncloud.android.lib.common.utils.Log_OC;
  49. import com.owncloud.android.lib.resources.shares.ShareType;
  50. import com.owncloud.android.utils.FileStorageUtils;
  51. import com.owncloud.android.utils.MimeType;
  52. import java.io.File;
  53. import java.util.ArrayList;
  54. /**
  55. * The ContentProvider for the ownCloud App.
  56. */
  57. public class FileContentProvider extends ContentProvider {
  58. private DataBaseHelper mDbHelper;
  59. private static final int SINGLE_FILE = 1;
  60. private static final int DIRECTORY = 2;
  61. private static final int ROOT_DIRECTORY = 3;
  62. private static final int SHARES = 4;
  63. private static final int CAPABILITIES = 5;
  64. private static final int UPLOADS = 6;
  65. private static final String TAG = FileContentProvider.class.getSimpleName();
  66. private final String MAX_SUCCESSFUL_UPLOADS = "30";
  67. private UriMatcher mUriMatcher;
  68. @Override
  69. public int delete(Uri uri, String where, String[] whereArgs) {
  70. //Log_OC.d(TAG, "Deleting " + uri + " at provider " + this);
  71. int count = 0;
  72. SQLiteDatabase db = mDbHelper.getWritableDatabase();
  73. db.beginTransaction();
  74. try {
  75. count = delete(db, uri, where, whereArgs);
  76. db.setTransactionSuccessful();
  77. } finally {
  78. db.endTransaction();
  79. }
  80. getContext().getContentResolver().notifyChange(uri, null);
  81. return count;
  82. }
  83. private int delete(SQLiteDatabase db, Uri uri, String where, String[] whereArgs) {
  84. int count = 0;
  85. switch (mUriMatcher.match(uri)) {
  86. case SINGLE_FILE:
  87. Cursor c = query(db, uri, null, where, whereArgs, null);
  88. String remoteId = "";
  89. if (c != null && c.moveToFirst()) {
  90. remoteId = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_REMOTE_ID));
  91. //ThumbnailsCacheManager.removeFileFromCache(remoteId);
  92. c.close();
  93. }
  94. Log_OC.d(TAG, "Removing FILE " + remoteId);
  95. count = db.delete(ProviderTableMeta.FILE_TABLE_NAME,
  96. ProviderTableMeta._ID
  97. + "="
  98. + uri.getPathSegments().get(1)
  99. + (!TextUtils.isEmpty(where) ? " AND (" + where
  100. + ")" : ""), whereArgs);
  101. break;
  102. case DIRECTORY:
  103. // deletion of folder is recursive
  104. /*
  105. Uri folderUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, Long.parseLong(uri.getPathSegments().get(1)));
  106. Cursor folder = query(db, folderUri, null, null, null, null);
  107. String folderName = "(unknown)";
  108. if (folder != null && folder.moveToFirst()) {
  109. folderName = folder.getString(folder.getColumnIndex(ProviderTableMeta.FILE_PATH));
  110. }
  111. */
  112. Cursor children = query(uri, null, null, null, null);
  113. if (children != null && children.moveToFirst()) {
  114. long childId;
  115. boolean isDir;
  116. while (!children.isAfterLast()) {
  117. childId = children.getLong(children.getColumnIndex(ProviderTableMeta._ID));
  118. isDir = MimeType.DIRECTORY.equals(children.getString(
  119. children.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)
  120. ));
  121. //remotePath = children.getString(children.getColumnIndex(ProviderTableMeta.FILE_PATH));
  122. if (isDir) {
  123. count += delete(
  124. db,
  125. ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_DIR, childId),
  126. null,
  127. null
  128. );
  129. } else {
  130. count += delete(
  131. db,
  132. ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, childId),
  133. null,
  134. null
  135. );
  136. }
  137. children.moveToNext();
  138. }
  139. children.close();
  140. } /*else {
  141. Log_OC.d(TAG, "No child to remove in DIRECTORY " + folderName);
  142. }
  143. Log_OC.d(TAG, "Removing DIRECTORY " + folderName + " (or maybe not) ");
  144. */
  145. count += db.delete(ProviderTableMeta.FILE_TABLE_NAME,
  146. ProviderTableMeta._ID
  147. + "="
  148. + uri.getPathSegments().get(1)
  149. + (!TextUtils.isEmpty(where) ? " AND (" + where
  150. + ")" : ""), whereArgs);
  151. /* Just for log
  152. if (folder != null) {
  153. folder.close();
  154. }*/
  155. break;
  156. case ROOT_DIRECTORY:
  157. //Log_OC.d(TAG, "Removing ROOT!");
  158. count = db.delete(ProviderTableMeta.FILE_TABLE_NAME, where, whereArgs);
  159. break;
  160. case SHARES:
  161. count = db.delete(ProviderTableMeta.OCSHARES_TABLE_NAME, where, whereArgs);
  162. break;
  163. case CAPABILITIES:
  164. count = db.delete(ProviderTableMeta.CAPABILITIES_TABLE_NAME, where, whereArgs);
  165. break;
  166. case UPLOADS:
  167. count = db.delete(ProviderTableMeta.UPLOADS_TABLE_NAME, where, whereArgs);
  168. break;
  169. default:
  170. //Log_OC.e(TAG, "Unknown uri " + uri);
  171. throw new IllegalArgumentException("Unknown uri: " + uri.toString());
  172. }
  173. return count;
  174. }
  175. @Override
  176. public String getType(Uri uri) {
  177. switch (mUriMatcher.match(uri)) {
  178. case ROOT_DIRECTORY:
  179. return ProviderTableMeta.CONTENT_TYPE;
  180. case SINGLE_FILE:
  181. return ProviderTableMeta.CONTENT_TYPE_ITEM;
  182. default:
  183. throw new IllegalArgumentException("Unknown Uri id."
  184. + uri.toString());
  185. }
  186. }
  187. @Override
  188. public Uri insert(Uri uri, ContentValues values) {
  189. Uri newUri = null;
  190. SQLiteDatabase db = mDbHelper.getWritableDatabase();
  191. db.beginTransaction();
  192. try {
  193. newUri = insert(db, uri, values);
  194. db.setTransactionSuccessful();
  195. } finally {
  196. db.endTransaction();
  197. }
  198. getContext().getContentResolver().notifyChange(newUri, null);
  199. return newUri;
  200. }
  201. private Uri insert(SQLiteDatabase db, Uri uri, ContentValues values) {
  202. switch (mUriMatcher.match(uri)){
  203. case ROOT_DIRECTORY:
  204. case SINGLE_FILE:
  205. String remotePath = values.getAsString(ProviderTableMeta.FILE_PATH);
  206. String accountName = values.getAsString(ProviderTableMeta.FILE_ACCOUNT_OWNER);
  207. String[] projection = new String[] {
  208. ProviderTableMeta._ID, ProviderTableMeta.FILE_PATH,
  209. ProviderTableMeta.FILE_ACCOUNT_OWNER
  210. };
  211. String where = ProviderTableMeta.FILE_PATH + "=? AND " +
  212. ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?";
  213. String[] whereArgs = new String[] {remotePath, accountName};
  214. Cursor doubleCheck = query(db, uri, projection, where, whereArgs, null);
  215. // ugly patch; serious refactorization is needed to reduce work in
  216. // FileDataStorageManager and bring it to FileContentProvider
  217. if (doubleCheck == null || !doubleCheck.moveToFirst()) {
  218. if (doubleCheck != null) {
  219. doubleCheck.close();
  220. }
  221. long rowId = db.insert(ProviderTableMeta.FILE_TABLE_NAME, null, values);
  222. if (rowId > 0) {
  223. return ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, rowId);
  224. } else {
  225. throw new SQLException("ERROR " + uri);
  226. }
  227. } else {
  228. // file is already inserted; race condition, let's avoid a duplicated entry
  229. Uri insertedFileUri = ContentUris.withAppendedId(
  230. ProviderTableMeta.CONTENT_URI_FILE,
  231. doubleCheck.getLong(doubleCheck.getColumnIndex(ProviderTableMeta._ID))
  232. );
  233. doubleCheck.close();
  234. return insertedFileUri;
  235. }
  236. case SHARES:
  237. Uri insertedShareUri = null;
  238. long rowId = db.insert(ProviderTableMeta.OCSHARES_TABLE_NAME, null, values);
  239. if (rowId >0) {
  240. insertedShareUri =
  241. ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_SHARE, rowId);
  242. } else {
  243. throw new SQLException("ERROR " + uri);
  244. }
  245. updateFilesTableAccordingToShareInsertion(db, values);
  246. return insertedShareUri;
  247. case CAPABILITIES:
  248. Uri insertedCapUri = null;
  249. long id = db.insert(ProviderTableMeta.CAPABILITIES_TABLE_NAME, null, values);
  250. if (id >0) {
  251. insertedCapUri =
  252. ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_CAPABILITIES, id);
  253. } else {
  254. throw new SQLException("ERROR " + uri);
  255. }
  256. return insertedCapUri;
  257. case UPLOADS:
  258. Uri insertedUploadUri = null;
  259. long uploadId = db.insert(ProviderTableMeta.UPLOADS_TABLE_NAME, null, values);
  260. if (uploadId >0) {
  261. insertedUploadUri =
  262. ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_UPLOADS, uploadId);
  263. trimSuccessfulUploads(db);
  264. } else {
  265. throw new SQLException("ERROR " + uri);
  266. }
  267. return insertedUploadUri;
  268. default:
  269. throw new IllegalArgumentException("Unknown uri id: " + uri);
  270. }
  271. }
  272. private void updateFilesTableAccordingToShareInsertion(
  273. SQLiteDatabase db, ContentValues newShare
  274. ) {
  275. ContentValues fileValues = new ContentValues();
  276. int newShareType = newShare.getAsInteger(ProviderTableMeta.OCSHARES_SHARE_TYPE);
  277. if (newShareType == ShareType.PUBLIC_LINK.getValue()) {
  278. fileValues.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, 1);
  279. } else if (
  280. newShareType == ShareType.USER.getValue() ||
  281. newShareType == ShareType.GROUP.getValue() ||
  282. newShareType == ShareType.FEDERATED.getValue() ) {
  283. fileValues.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, 1);
  284. }
  285. String where = ProviderTableMeta.FILE_PATH + "=? AND " +
  286. ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?";
  287. String[] whereArgs = new String[] {
  288. newShare.getAsString(ProviderTableMeta.OCSHARES_PATH),
  289. newShare.getAsString(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER)
  290. };
  291. db.update(ProviderTableMeta.FILE_TABLE_NAME, fileValues, where, whereArgs);
  292. }
  293. @Override
  294. public boolean onCreate() {
  295. mDbHelper = new DataBaseHelper(getContext());
  296. String authority = getContext().getResources().getString(R.string.authority);
  297. mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  298. mUriMatcher.addURI(authority, null, ROOT_DIRECTORY);
  299. mUriMatcher.addURI(authority, "file/", SINGLE_FILE);
  300. mUriMatcher.addURI(authority, "file/#", SINGLE_FILE);
  301. mUriMatcher.addURI(authority, "dir/", DIRECTORY);
  302. mUriMatcher.addURI(authority, "dir/#", DIRECTORY);
  303. mUriMatcher.addURI(authority, "shares/", SHARES);
  304. mUriMatcher.addURI(authority, "shares/#", SHARES);
  305. mUriMatcher.addURI(authority, "capabilities/", CAPABILITIES);
  306. mUriMatcher.addURI(authority, "capabilities/#", CAPABILITIES);
  307. mUriMatcher.addURI(authority, "uploads/", UPLOADS);
  308. mUriMatcher.addURI(authority, "uploads/#", UPLOADS);
  309. return true;
  310. }
  311. @Override
  312. public Cursor query(
  313. Uri uri,
  314. String[] projection,
  315. String selection,
  316. String[] selectionArgs,
  317. String sortOrder
  318. ) {
  319. Cursor result = null;
  320. SQLiteDatabase db = mDbHelper.getReadableDatabase();
  321. db.beginTransaction();
  322. try {
  323. result = query(db, uri, projection, selection, selectionArgs, sortOrder);
  324. db.setTransactionSuccessful();
  325. } finally {
  326. db.endTransaction();
  327. }
  328. return result;
  329. }
  330. private Cursor query(
  331. SQLiteDatabase db,
  332. Uri uri,
  333. String[] projection,
  334. String selection,
  335. String[] selectionArgs,
  336. String sortOrder
  337. ) {
  338. SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();
  339. sqlQuery.setTables(ProviderTableMeta.FILE_TABLE_NAME);
  340. switch (mUriMatcher.match(uri)) {
  341. case ROOT_DIRECTORY:
  342. break;
  343. case DIRECTORY:
  344. String folderId = uri.getPathSegments().get(1);
  345. sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="
  346. + folderId);
  347. break;
  348. case SINGLE_FILE:
  349. if (uri.getPathSegments().size() > 1) {
  350. sqlQuery.appendWhere(ProviderTableMeta._ID + "="
  351. + uri.getPathSegments().get(1));
  352. }
  353. break;
  354. case SHARES:
  355. sqlQuery.setTables(ProviderTableMeta.OCSHARES_TABLE_NAME);
  356. if (uri.getPathSegments().size() > 1) {
  357. sqlQuery.appendWhere(ProviderTableMeta._ID + "="
  358. + uri.getPathSegments().get(1));
  359. }
  360. break;
  361. case CAPABILITIES:
  362. sqlQuery.setTables(ProviderTableMeta.CAPABILITIES_TABLE_NAME);
  363. if (uri.getPathSegments().size() > 1) {
  364. sqlQuery.appendWhere(ProviderTableMeta._ID + "="
  365. + uri.getPathSegments().get(1));
  366. }
  367. break;
  368. case UPLOADS:
  369. sqlQuery.setTables(ProviderTableMeta.UPLOADS_TABLE_NAME);
  370. if (uri.getPathSegments().size() > 1) {
  371. sqlQuery.appendWhere(ProviderTableMeta._ID + "="
  372. + uri.getPathSegments().get(1));
  373. }
  374. break;
  375. default:
  376. throw new IllegalArgumentException("Unknown uri id: " + uri);
  377. }
  378. String order;
  379. if (TextUtils.isEmpty(sortOrder)) {
  380. switch (mUriMatcher.match(uri)) {
  381. case SHARES:
  382. order = ProviderTableMeta.OCSHARES_DEFAULT_SORT_ORDER;
  383. break;
  384. case CAPABILITIES:
  385. order = ProviderTableMeta.CAPABILITIES_DEFAULT_SORT_ORDER;
  386. break;
  387. case UPLOADS:
  388. order = ProviderTableMeta.UPLOADS_DEFAULT_SORT_ORDER;
  389. break;
  390. default: // Files
  391. order = ProviderTableMeta.FILE_DEFAULT_SORT_ORDER;
  392. break;
  393. }
  394. } else {
  395. order = sortOrder;
  396. }
  397. // DB case_sensitive
  398. db.execSQL("PRAGMA case_sensitive_like = true");
  399. Cursor c = sqlQuery.query(db, projection, selection, selectionArgs, null, null, order);
  400. c.setNotificationUri(getContext().getContentResolver(), uri);
  401. return c;
  402. }
  403. @Override
  404. public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
  405. int count = 0;
  406. SQLiteDatabase db = mDbHelper.getWritableDatabase();
  407. db.beginTransaction();
  408. try {
  409. count = update(db, uri, values, selection, selectionArgs);
  410. db.setTransactionSuccessful();
  411. } finally {
  412. db.endTransaction();
  413. }
  414. getContext().getContentResolver().notifyChange(uri, null);
  415. return count;
  416. }
  417. private int update(
  418. SQLiteDatabase db,
  419. Uri uri,
  420. ContentValues values,
  421. String selection,
  422. String[] selectionArgs
  423. ) {
  424. switch (mUriMatcher.match(uri)) {
  425. case DIRECTORY:
  426. return 0; //updateFolderSize(db, selectionArgs[0]);
  427. case SHARES:
  428. return db.update(
  429. ProviderTableMeta.OCSHARES_TABLE_NAME, values, selection, selectionArgs
  430. );
  431. case CAPABILITIES:
  432. return db.update(
  433. ProviderTableMeta.CAPABILITIES_TABLE_NAME, values, selection, selectionArgs
  434. );
  435. case UPLOADS:
  436. int ret = db.update(
  437. ProviderTableMeta.UPLOADS_TABLE_NAME, values, selection, selectionArgs
  438. );
  439. trimSuccessfulUploads(db);
  440. return ret;
  441. default:
  442. return db.update(
  443. ProviderTableMeta.FILE_TABLE_NAME, values, selection, selectionArgs
  444. );
  445. }
  446. }
  447. @Override
  448. public ContentProviderResult[] applyBatch (ArrayList<ContentProviderOperation> operations)
  449. throws OperationApplicationException {
  450. Log_OC.d("FileContentProvider", "applying batch in provider " + this +
  451. " (temporary: " + isTemporary() + ")" );
  452. ContentProviderResult[] results = new ContentProviderResult[operations.size()];
  453. int i=0;
  454. SQLiteDatabase db = mDbHelper.getWritableDatabase();
  455. db.beginTransaction(); // it's supposed that transactions can be nested
  456. try {
  457. for (ContentProviderOperation operation : operations) {
  458. results[i] = operation.apply(this, results, i);
  459. i++;
  460. }
  461. db.setTransactionSuccessful();
  462. } finally {
  463. db.endTransaction();
  464. }
  465. Log_OC.d("FileContentProvider", "applied batch in provider " + this);
  466. return results;
  467. }
  468. class DataBaseHelper extends SQLiteOpenHelper {
  469. public DataBaseHelper(Context context) {
  470. super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);
  471. }
  472. @Override
  473. public void onCreate(SQLiteDatabase db) {
  474. // files table
  475. Log_OC.i("SQL", "Entering in onCreate");
  476. createFilesTable(db);
  477. // Create ocshares table
  478. createOCSharesTable(db);
  479. // Create capabilities table
  480. createCapabilitiesTable(db);
  481. // Create uploads table
  482. createUploadsTable(db);
  483. // Create synced folders table
  484. createSyncedFoldersTable(db);
  485. }
  486. @Override
  487. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  488. Log_OC.i("SQL", "Entering in onUpgrade");
  489. boolean upgraded = false;
  490. if (oldVersion == 1 && newVersion >= 2) {
  491. Log_OC.i("SQL", "Entering in the #1 ADD in onUpgrade");
  492. db.execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  493. " ADD COLUMN " + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER " +
  494. " DEFAULT 0");
  495. upgraded = true;
  496. }
  497. if (oldVersion < 3 && newVersion >= 3) {
  498. Log_OC.i("SQL", "Entering in the #2 ADD in onUpgrade");
  499. db.beginTransaction();
  500. try {
  501. db.execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  502. " ADD COLUMN " + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA +
  503. " INTEGER " + " DEFAULT 0");
  504. // assume there are not local changes pending to upload
  505. db.execSQL("UPDATE " + ProviderTableMeta.FILE_TABLE_NAME +
  506. " SET " + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " = "
  507. + System.currentTimeMillis() +
  508. " WHERE " + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL");
  509. upgraded = true;
  510. db.setTransactionSuccessful();
  511. } finally {
  512. db.endTransaction();
  513. }
  514. }
  515. if (oldVersion < 4 && newVersion >= 4) {
  516. Log_OC.i("SQL", "Entering in the #3 ADD in onUpgrade");
  517. db.beginTransaction();
  518. try {
  519. db.execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  520. " ADD COLUMN " + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA +
  521. " INTEGER " + " DEFAULT 0");
  522. db.execSQL("UPDATE " + ProviderTableMeta.FILE_TABLE_NAME +
  523. " SET " + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " = " +
  524. ProviderTableMeta.FILE_MODIFIED +
  525. " WHERE " + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL");
  526. upgraded = true;
  527. db.setTransactionSuccessful();
  528. } finally {
  529. db.endTransaction();
  530. }
  531. }
  532. if (!upgraded)
  533. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  534. ", newVersion == " + newVersion);
  535. if (oldVersion < 5 && newVersion >= 5) {
  536. Log_OC.i("SQL", "Entering in the #4 ADD in onUpgrade");
  537. db.beginTransaction();
  538. try {
  539. db.execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  540. " ADD COLUMN " + ProviderTableMeta.FILE_ETAG + " TEXT " +
  541. " DEFAULT NULL");
  542. upgraded = true;
  543. db.setTransactionSuccessful();
  544. } finally {
  545. db.endTransaction();
  546. }
  547. }
  548. if (!upgraded)
  549. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  550. ", newVersion == " + newVersion);
  551. if (oldVersion < 6 && newVersion >= 6) {
  552. Log_OC.i("SQL", "Entering in the #5 ADD in onUpgrade");
  553. db.beginTransaction();
  554. try {
  555. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  556. " ADD COLUMN " + ProviderTableMeta.FILE_SHARED_VIA_LINK + " INTEGER " +
  557. " DEFAULT 0");
  558. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  559. " ADD COLUMN " + ProviderTableMeta.FILE_PUBLIC_LINK + " TEXT " +
  560. " DEFAULT NULL");
  561. // Create table ocshares
  562. createOCSharesTable(db);
  563. upgraded = true;
  564. db.setTransactionSuccessful();
  565. } finally {
  566. db.endTransaction();
  567. }
  568. }
  569. if (!upgraded)
  570. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  571. ", newVersion == " + newVersion);
  572. if (oldVersion < 7 && newVersion >= 7) {
  573. Log_OC.i("SQL", "Entering in the #7 ADD in onUpgrade");
  574. db.beginTransaction();
  575. try {
  576. db.execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  577. " ADD COLUMN " + ProviderTableMeta.FILE_PERMISSIONS + " TEXT " +
  578. " DEFAULT NULL");
  579. db.execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  580. " ADD COLUMN " + ProviderTableMeta.FILE_REMOTE_ID + " TEXT " +
  581. " DEFAULT NULL");
  582. upgraded = true;
  583. db.setTransactionSuccessful();
  584. } finally {
  585. db.endTransaction();
  586. }
  587. }
  588. if (!upgraded)
  589. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  590. ", newVersion == " + newVersion);
  591. if (oldVersion < 8 && newVersion >= 8) {
  592. Log_OC.i("SQL", "Entering in the #8 ADD in onUpgrade");
  593. db.beginTransaction();
  594. try {
  595. db.execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  596. " ADD COLUMN " + ProviderTableMeta.FILE_UPDATE_THUMBNAIL + " INTEGER " +
  597. " DEFAULT 0");
  598. upgraded = true;
  599. db.setTransactionSuccessful();
  600. } finally {
  601. db.endTransaction();
  602. }
  603. }
  604. if (!upgraded)
  605. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  606. ", newVersion == " + newVersion);
  607. if (oldVersion < 9 && newVersion >= 9) {
  608. Log_OC.i("SQL", "Entering in the #9 ADD in onUpgrade");
  609. db.beginTransaction();
  610. try {
  611. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  612. " ADD COLUMN " + ProviderTableMeta.FILE_IS_DOWNLOADING + " INTEGER " +
  613. " DEFAULT 0");
  614. upgraded = true;
  615. db.setTransactionSuccessful();
  616. } finally {
  617. db.endTransaction();
  618. }
  619. }
  620. if (!upgraded)
  621. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  622. ", newVersion == " + newVersion);
  623. if (oldVersion < 10 && newVersion >= 10) {
  624. Log_OC.i("SQL", "Entering in the #10 ADD in onUpgrade");
  625. updateAccountName(db);
  626. upgraded = true;
  627. }
  628. if (!upgraded)
  629. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  630. ", newVersion == " + newVersion);
  631. if (oldVersion < 11 && newVersion >= 11) {
  632. Log_OC.i("SQL", "Entering in the #11 ADD in onUpgrade");
  633. db.beginTransaction();
  634. try {
  635. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  636. " ADD COLUMN " + ProviderTableMeta.FILE_ETAG_IN_CONFLICT + " TEXT " +
  637. " DEFAULT NULL");
  638. upgraded = true;
  639. db.setTransactionSuccessful();
  640. } finally {
  641. db.endTransaction();
  642. }
  643. }
  644. if (!upgraded)
  645. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  646. ", newVersion == " + newVersion);
  647. if (oldVersion < 12 && newVersion >= 12) {
  648. Log_OC.i("SQL", "Entering in the #12 ADD in onUpgrade");
  649. db.beginTransaction();
  650. try {
  651. db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
  652. " ADD COLUMN " + ProviderTableMeta.FILE_SHARED_WITH_SHAREE + " INTEGER " +
  653. " DEFAULT 0");
  654. upgraded = true;
  655. db.setTransactionSuccessful();
  656. } finally {
  657. db.endTransaction();
  658. }
  659. }
  660. if (!upgraded)
  661. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  662. ", newVersion == " + newVersion);
  663. if (oldVersion < 13 && newVersion >= 13) {
  664. Log_OC.i("SQL", "Entering in the #13 ADD in onUpgrade");
  665. db.beginTransaction();
  666. try {
  667. // Create capabilities table
  668. createCapabilitiesTable(db);
  669. upgraded = true;
  670. db.setTransactionSuccessful();
  671. } finally {
  672. db.endTransaction();
  673. }
  674. }
  675. if (oldVersion < 14 && newVersion >= 14) {
  676. Log_OC.i("SQL", "Entering in the #14 ADD in onUpgrade");
  677. db.beginTransaction();
  678. try {
  679. // drop old instant_upload table
  680. db.execSQL("DROP TABLE IF EXISTS " + "instant_upload" + ";");
  681. // Create uploads table
  682. createUploadsTable(db);
  683. upgraded = true;
  684. db.setTransactionSuccessful();
  685. } finally {
  686. db.endTransaction();
  687. }
  688. }
  689. if (oldVersion < 15 && newVersion >= 15) {
  690. Log_OC.i("SQL", "Entering in the #15 ADD in onUpgrade");
  691. db.beginTransaction();
  692. try {
  693. // drop old capabilities table
  694. db.execSQL("DROP TABLE IF EXISTS " + "capabilities" + ";");
  695. // Create uploads table
  696. createCapabilitiesTable(db);
  697. upgraded = true;
  698. db.setTransactionSuccessful();
  699. } finally {
  700. db.endTransaction();
  701. }
  702. }
  703. if (oldVersion < 16 && newVersion >= 16) {
  704. Log_OC.i("SQL", "Entering in the #16 ADD synced folders table");
  705. db.beginTransaction();
  706. try {
  707. // Create synced folders table
  708. createSyncedFoldersTable(db);
  709. upgraded = true;
  710. db.setTransactionSuccessful();
  711. } finally {
  712. db.endTransaction();
  713. }
  714. }
  715. if (!upgraded)
  716. Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
  717. ", newVersion == " + newVersion);
  718. }
  719. }
  720. private void createFilesTable(SQLiteDatabase db){
  721. db.execSQL("CREATE TABLE " + ProviderTableMeta.FILE_TABLE_NAME + "("
  722. + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
  723. + ProviderTableMeta.FILE_NAME + " TEXT, "
  724. + ProviderTableMeta.FILE_PATH + " TEXT, "
  725. + ProviderTableMeta.FILE_PARENT + " INTEGER, "
  726. + ProviderTableMeta.FILE_CREATION + " INTEGER, "
  727. + ProviderTableMeta.FILE_MODIFIED + " INTEGER, "
  728. + ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, "
  729. + ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, "
  730. + ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, "
  731. + ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT, "
  732. + ProviderTableMeta.FILE_LAST_SYNC_DATE + " INTEGER, "
  733. + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER, "
  734. + ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + " INTEGER, "
  735. + ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + " INTEGER, "
  736. + ProviderTableMeta.FILE_ETAG + " TEXT, "
  737. + ProviderTableMeta.FILE_SHARED_VIA_LINK + " INTEGER, "
  738. + ProviderTableMeta.FILE_PUBLIC_LINK + " TEXT, "
  739. + ProviderTableMeta.FILE_PERMISSIONS + " TEXT null,"
  740. + ProviderTableMeta.FILE_REMOTE_ID + " TEXT null,"
  741. + ProviderTableMeta.FILE_UPDATE_THUMBNAIL + " INTEGER," //boolean
  742. + ProviderTableMeta.FILE_IS_DOWNLOADING + " INTEGER," //boolean
  743. + ProviderTableMeta.FILE_ETAG_IN_CONFLICT + " TEXT,"
  744. + ProviderTableMeta.FILE_SHARED_WITH_SHAREE + " INTEGER);"
  745. );
  746. }
  747. private void createOCSharesTable(SQLiteDatabase db) {
  748. // Create ocshares table
  749. db.execSQL("CREATE TABLE " + ProviderTableMeta.OCSHARES_TABLE_NAME + "("
  750. + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
  751. + ProviderTableMeta.OCSHARES_FILE_SOURCE + " INTEGER, "
  752. + ProviderTableMeta.OCSHARES_ITEM_SOURCE + " INTEGER, "
  753. + ProviderTableMeta.OCSHARES_SHARE_TYPE + " INTEGER, "
  754. + ProviderTableMeta.OCSHARES_SHARE_WITH + " TEXT, "
  755. + ProviderTableMeta.OCSHARES_PATH + " TEXT, "
  756. + ProviderTableMeta.OCSHARES_PERMISSIONS+ " INTEGER, "
  757. + ProviderTableMeta.OCSHARES_SHARED_DATE + " INTEGER, "
  758. + ProviderTableMeta.OCSHARES_EXPIRATION_DATE + " INTEGER, "
  759. + ProviderTableMeta.OCSHARES_TOKEN + " TEXT, "
  760. + ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME + " TEXT, "
  761. + ProviderTableMeta.OCSHARES_IS_DIRECTORY + " INTEGER, " // boolean
  762. + ProviderTableMeta.OCSHARES_USER_ID + " INTEGER, "
  763. + ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + " INTEGER,"
  764. + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + " TEXT );" );
  765. }
  766. private void createCapabilitiesTable(SQLiteDatabase db){
  767. // Create capabilities table
  768. db.execSQL("CREATE TABLE " + ProviderTableMeta.CAPABILITIES_TABLE_NAME + "("
  769. + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
  770. + ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME + " TEXT, "
  771. + ProviderTableMeta.CAPABILITIES_VERSION_MAYOR + " INTEGER, "
  772. + ProviderTableMeta.CAPABILITIES_VERSION_MINOR + " INTEGER, "
  773. + ProviderTableMeta.CAPABILITIES_VERSION_MICRO + " INTEGER, "
  774. + ProviderTableMeta.CAPABILITIES_VERSION_STRING + " TEXT, "
  775. + ProviderTableMeta.CAPABILITIES_VERSION_EDITION + " TEXT, "
  776. + ProviderTableMeta.CAPABILITIES_CORE_POLLINTERVAL + " INTEGER, "
  777. + ProviderTableMeta.CAPABILITIES_SHARING_API_ENABLED + " INTEGER, " // boolean
  778. + ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ENABLED + " INTEGER, " // boolean
  779. + ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_PASSWORD_ENFORCED + " INTEGER, " // boolean
  780. + ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENABLED + " INTEGER, " // boolean
  781. + ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_DAYS + " INTEGER, "
  782. + ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENFORCED + " INTEGER, " // boolean
  783. + ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_SEND_MAIL + " INTEGER, " // boolean
  784. + ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_UPLOAD + " INTEGER, " // boolean
  785. + ProviderTableMeta.CAPABILITIES_SHARING_USER_SEND_MAIL + " INTEGER, " // boolean
  786. + ProviderTableMeta.CAPABILITIES_SHARING_RESHARING + " INTEGER, " // boolean
  787. + ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_OUTGOING + " INTEGER, " // boolean
  788. + ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_INCOMING + " INTEGER, " // boolean
  789. + ProviderTableMeta.CAPABILITIES_FILES_BIGFILECHUNKING + " INTEGER, " // boolean
  790. + ProviderTableMeta.CAPABILITIES_FILES_UNDELETE + " INTEGER, " // boolean
  791. + ProviderTableMeta.CAPABILITIES_FILES_VERSIONING + " INTEGER, " // boolean
  792. + ProviderTableMeta.CAPABILITIES_FILES_DROP + " INTEGER );" ); // boolean
  793. }
  794. private void createUploadsTable(SQLiteDatabase db){
  795. // Create uploads table
  796. db.execSQL("CREATE TABLE " + ProviderTableMeta.UPLOADS_TABLE_NAME + "("
  797. + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "
  798. + ProviderTableMeta.UPLOADS_LOCAL_PATH + " TEXT, "
  799. + ProviderTableMeta.UPLOADS_REMOTE_PATH + " TEXT, "
  800. + ProviderTableMeta.UPLOADS_ACCOUNT_NAME + " TEXT, "
  801. + ProviderTableMeta.UPLOADS_FILE_SIZE + " LONG, "
  802. + ProviderTableMeta.UPLOADS_STATUS + " INTEGER, " // UploadStatus
  803. + ProviderTableMeta.UPLOADS_LOCAL_BEHAVIOUR + " INTEGER, " // Upload LocalBehaviour
  804. + ProviderTableMeta.UPLOADS_UPLOAD_TIME + " INTEGER, "
  805. + ProviderTableMeta.UPLOADS_FORCE_OVERWRITE + " INTEGER, " // boolean
  806. + ProviderTableMeta.UPLOADS_IS_CREATE_REMOTE_FOLDER + " INTEGER, " // boolean
  807. + ProviderTableMeta.UPLOADS_UPLOAD_END_TIMESTAMP + " INTEGER, "
  808. + ProviderTableMeta.UPLOADS_LAST_RESULT + " INTEGER, " // Upload LastResult
  809. + ProviderTableMeta.UPLOADS_CREATED_BY + " INTEGER );" // Upload createdBy
  810. );
  811. /* before:
  812. // PRIMARY KEY should always imply NOT NULL. Unfortunately, due to a
  813. // bug in some early versions, this is not the case in SQLite.
  814. //db.execSQL("CREATE TABLE " + TABLE_UPLOAD + " (" + " path TEXT PRIMARY KEY NOT NULL UNIQUE,"
  815. // + " uploadStatus INTEGER NOT NULL, uploadObject TEXT NOT NULL);");
  816. // uploadStatus is used to easy filtering, it has precedence over
  817. // uploadObject.getUploadStatus()
  818. */
  819. }
  820. private void createSyncedFoldersTable(SQLiteDatabase db){
  821. db.execSQL("CREATE TABLE " + ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME + "("
  822. + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, " // id
  823. + ProviderTableMeta.SYNCED_FOLDER_LOCAL_PATH + " TEXT, " // local path
  824. + ProviderTableMeta.SYNCED_FOLDER_REMOTE_PATH + " TEXT, " // remote path
  825. + ProviderTableMeta.SYNCED_FOLDER_WIFI_ONLY + " INTEGER, " // wifi_only
  826. + ProviderTableMeta.SYNCED_FOLDER_CHARGING_ONLY + " INTEGER, " // charging only
  827. + ProviderTableMeta.SYNCED_FOLDER_ENABLED + " INTEGER, " // enabled
  828. + ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_BY_DATE + " INTEGER, " // subfolder by date
  829. + ProviderTableMeta.SYNCED_FOLDER_ACCOUNT + " INTEGER, " // account
  830. + ProviderTableMeta.SYNCED_FOLDER_UPLOAD_OPTION + " INTEGER );" // upload action
  831. );
  832. // TODO Tobi remove after testing
  833. db.execSQL("INSERT INTO " + ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME + "("
  834. + ProviderTableMeta.SYNCED_FOLDER_LOCAL_PATH + ", " // local path
  835. + ProviderTableMeta.SYNCED_FOLDER_REMOTE_PATH + ", " // remote path
  836. + ProviderTableMeta.SYNCED_FOLDER_WIFI_ONLY + ", " // wifi_only
  837. + ProviderTableMeta.SYNCED_FOLDER_CHARGING_ONLY + ", " // charging only
  838. + ProviderTableMeta.SYNCED_FOLDER_ENABLED + ", " // enabled
  839. + ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_BY_DATE + ", " // subfolder by date
  840. + ProviderTableMeta.SYNCED_FOLDER_ACCOUNT + ", " // account
  841. + ProviderTableMeta.SYNCED_FOLDER_UPLOAD_OPTION + ") " // upload action
  842. + "VALUES ('/sdcard/DCIM/', 'syncTest', 0, 0, 1, 1, 'tobi', 1)");
  843. }
  844. /**
  845. * Version 10 of database does not modify its scheme. It coincides with the upgrade of the ownCloud account names
  846. * structure to include in it the path to the server instance. Updating the account names and path to local files
  847. * in the files table is a must to keep the existing account working and the database clean.
  848. *
  849. * See {@link com.owncloud.android.authentication.AccountUtils#updateAccountVersion(android.content.Context)}
  850. *
  851. * @param db Database where table of files is included.
  852. */
  853. private void updateAccountName(SQLiteDatabase db){
  854. Log_OC.d("SQL", "THREAD: " + Thread.currentThread().getName());
  855. AccountManager ama = AccountManager.get(getContext());
  856. try {
  857. // get accounts from AccountManager ; we can't be sure if accounts in it are updated or not although
  858. // we know the update was previously done in {link @FileActivity#onCreate} because the changes through
  859. // AccountManager are not synchronous
  860. Account[] accounts = AccountManager.get(getContext()).getAccountsByType(
  861. MainApp.getAccountType());
  862. String serverUrl, username, oldAccountName, newAccountName;
  863. for (Account account : accounts) {
  864. // build both old and new account name
  865. serverUrl = ama.getUserData(account, AccountUtils.Constants.KEY_OC_BASE_URL);
  866. username = AccountUtils.getUsernameForAccount(account);
  867. oldAccountName = AccountUtils.buildAccountNameOld(Uri.parse(serverUrl), username);
  868. newAccountName = AccountUtils.buildAccountName(Uri.parse(serverUrl), username);
  869. // update values in database
  870. db.beginTransaction();
  871. try {
  872. ContentValues cv = new ContentValues();
  873. cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, newAccountName);
  874. int num = db.update(ProviderTableMeta.FILE_TABLE_NAME,
  875. cv,
  876. ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
  877. new String[]{oldAccountName});
  878. Log_OC.d("SQL", "Updated account in database: old name == " + oldAccountName +
  879. ", new name == " + newAccountName + " (" + num + " rows updated )");
  880. // update path for downloaded files
  881. updateDownloadedFiles(db, newAccountName, oldAccountName);
  882. db.setTransactionSuccessful();
  883. } catch (SQLException e) {
  884. Log_OC.e(TAG, "SQL Exception upgrading account names or paths in database", e);
  885. } finally {
  886. db.endTransaction();
  887. }
  888. }
  889. } catch (Exception e) {
  890. Log_OC.e(TAG, "Exception upgrading account names or paths in database", e);
  891. }
  892. }
  893. /**
  894. * Rename the local ownCloud folder of one account to match the a rename of the account itself. Updates the
  895. * table of files in database so that the paths to the local files keep being the same.
  896. *
  897. * @param db Database where table of files is included.
  898. * @param newAccountName New name for the target OC account.
  899. * @param oldAccountName Old name of the target OC account.
  900. */
  901. private void updateDownloadedFiles(SQLiteDatabase db, String newAccountName,
  902. String oldAccountName) {
  903. String whereClause = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
  904. ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL";
  905. Cursor c = db.query(ProviderTableMeta.FILE_TABLE_NAME,
  906. null,
  907. whereClause,
  908. new String[]{newAccountName},
  909. null, null, null);
  910. try {
  911. if (c.moveToFirst()) {
  912. // create storage path
  913. String oldAccountPath = FileStorageUtils.getSavePath(oldAccountName);
  914. String newAccountPath = FileStorageUtils.getSavePath(newAccountName);
  915. // move files
  916. File oldAccountFolder = new File(oldAccountPath);
  917. File newAccountFolder = new File(newAccountPath);
  918. oldAccountFolder.renameTo(newAccountFolder);
  919. // update database
  920. do {
  921. // Update database
  922. String oldPath = c.getString(
  923. c.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
  924. OCFile file = new OCFile(
  925. c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PATH)));
  926. String newPath = FileStorageUtils.getDefaultSavePathFor(newAccountName, file);
  927. ContentValues cv = new ContentValues();
  928. cv.put(ProviderTableMeta.FILE_STORAGE_PATH, newPath);
  929. db.update(ProviderTableMeta.FILE_TABLE_NAME,
  930. cv,
  931. ProviderTableMeta.FILE_STORAGE_PATH + "=?",
  932. new String[]{oldPath});
  933. Log_OC.v("SQL", "Updated path of downloaded file: old file name == " + oldPath +
  934. ", new file name == " + newPath);
  935. } while (c.moveToNext());
  936. }
  937. } finally {
  938. c.close();
  939. }
  940. }
  941. /**
  942. * Grants that total count of successful uploads stored is not greater than MAX_SUCCESSFUL_UPLOADS.
  943. *
  944. * Removes older uploads if needed.
  945. */
  946. private void trimSuccessfulUploads(SQLiteDatabase db) {
  947. Cursor c = null;
  948. try {
  949. c = db.rawQuery(
  950. "delete from " + ProviderTableMeta.UPLOADS_TABLE_NAME +
  951. " where " + ProviderTableMeta.UPLOADS_STATUS + " == "
  952. + UploadsStorageManager.UploadStatus.UPLOAD_SUCCEEDED.getValue() +
  953. " and " + ProviderTableMeta._ID +
  954. " not in (select " + ProviderTableMeta._ID +
  955. " from " + ProviderTableMeta.UPLOADS_TABLE_NAME +
  956. " where " + ProviderTableMeta.UPLOADS_STATUS + " == "
  957. + UploadsStorageManager.UploadStatus.UPLOAD_SUCCEEDED.getValue() +
  958. " order by " + ProviderTableMeta.UPLOADS_UPLOAD_END_TIMESTAMP +
  959. " desc limit " + MAX_SUCCESSFUL_UPLOADS +
  960. ")",
  961. null
  962. );
  963. c.moveToFirst(); // do something with the cursor, or deletion doesn't happen; true story
  964. } catch (Exception e) {
  965. Log_OC.e(
  966. TAG,
  967. "Something wrong trimming successful uploads, database could grow more than expected",
  968. e
  969. );
  970. } finally {
  971. if (c!= null) {
  972. c.close();
  973. }
  974. }
  975. }
  976. }