FileContentProvider.java 49 KB

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