public void update(JobRequest request, ContentValues contentValues) { SQLiteDatabase database = null; mLock.writeLock().lock(); try { updateRequestInCache(request); database = getDatabase(); database.update(JOB_TABLE_NAME, contentValues, COLUMN_ID + "=?", new String[]{String.valueOf(request.getJobId())}); } catch (Exception e) { // catch the exception here and keep what's in the database CAT.e(e, "could not update %s", request); } finally { closeDatabase(database); mLock.writeLock().unlock(); } }
private boolean remove(@Nullable JobRequest request, int jobId) { SQLiteDatabase database = null; mLock.writeLock().lock(); try { mCacheId.remove(jobId); database = getDatabase(); database.delete(JOB_TABLE_NAME, COLUMN_ID + "=?", new String[]{String.valueOf(jobId)}); return true; } catch (Exception e) { CAT.e(e, "could not delete %d %s", jobId, request); addFailedDeleteId(jobId); return false; } finally { closeDatabase(database); mLock.writeLock().unlock(); } }
@VisibleForTesting /*package*/ int getMaxJobId() { SQLiteDatabase database = null; Cursor cursor = null; int jobId = 0; try { database = getDatabase(); cursor = database.rawQuery("SELECT MAX(" + COLUMN_ID + ") FROM " + JOB_TABLE_NAME, null); if (cursor != null && cursor.moveToFirst()) { jobId = cursor.getInt(0); } } catch (Exception e) { CAT.e(e); } finally { closeCursor(cursor); closeDatabase(database); } return Math.max(JobConfig.getJobIdOffset(), Math.max(jobId, mPreferences.getInt(JOB_ID_COUNTER, 0))); }
database = getDatabase(); cursor = database.query(JOB_TABLE_NAME, null, where, args, null, null, null);
@SuppressWarnings("SameParameterValue") private JobRequest load(int id, boolean includeStarted) { if (didFailToDelete(id)) { return null; } SQLiteDatabase database = null; Cursor cursor = null; try { String where = COLUMN_ID + "=?"; if (!includeStarted) { where += " AND " + COLUMN_STARTED + "<=0"; } database = getDatabase(); cursor = database.query(JOB_TABLE_NAME, null, where, new String[]{String.valueOf(id)}, null, null, null); if (cursor != null && cursor.moveToFirst()) { return JobRequest.fromCursor(cursor); } } catch (Exception e) { CAT.e(e, "could not load id %d", id); } finally { closeCursor(cursor); closeDatabase(database); } return null; }
private void store(JobRequest request) { ContentValues contentValues = request.toContentValues(); SQLiteDatabase database = null; try { database = getDatabase(); /* * It could happen that a conflict with the job ID occurs, when a job was cancelled (cancelAndEdit()) * the builder object scheduled twice. In this case the last call wins and the value in the database * will be overwritten. */ if (database.insertWithOnConflict(JOB_TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_REPLACE) < 0) { throw new SQLException("Couldn't insert job request into database"); } } finally { closeDatabase(database); } }
@Test public void verifyDeleteWhileOpening() { Context context = RuntimeEnvironment.application; String filePath = getClass().getResource("/databases/corrupted.db").getPath(); final long originalLength = new File(filePath).length(); assertThat(new File(filePath).exists()).isTrue(); JobStorage jobStorage = new JobStorage(context, filePath); SQLiteDatabase database = jobStorage.getDatabase(); assertThat(database).isNotNull(); assertThat(database.isOpen()).isTrue(); assertThat(originalLength).isNotEqualTo(new File(filePath).length()); File databaseFile = new File(database.getPath()); assertThat(databaseFile.exists()).isTrue(); assertThat(databaseFile.isFile()).isTrue(); } }
@Test public void verifyDeleteAfterCorruptionWhileOpen() { Context context = RuntimeEnvironment.application; JobStorage jobStorage = new JobStorage(context); SQLiteDatabase database = jobStorage.getDatabase(); assertThat(database).isNotNull(); assertThat(database.isOpen()).isTrue(); File file = new File(database.getPath()); assertThat(file.exists()).isTrue(); assertThat(file.isFile()).isTrue(); new JobStorageDatabaseErrorHandler().onCorruption(database); assertThat(file.exists()).isFalse(); }
@Test public void verifyDeleteAfterCorruptionWhileClosed() { Context context = RuntimeEnvironment.application; JobStorage jobStorage = new JobStorage(context); SQLiteDatabase database = jobStorage.getDatabase(); assertThat(database).isNotNull(); assertThat(database.isOpen()).isTrue(); File file = new File(database.getPath()); assertThat(file.exists()).isTrue(); assertThat(file.isFile()).isTrue(); database.close(); new JobStorageDatabaseErrorHandler().onCorruption(database); assertThat(file.exists()).isFalse(); }
@Test public void verifyDeleteWithApi14() { Context context = RuntimeEnvironment.application; JobStorage jobStorage = new JobStorage(context); SQLiteDatabase database = jobStorage.getDatabase(); assertThat(database).isNotNull(); assertThat(database.isOpen()).isTrue(); File file = new File(database.getPath()); assertThat(file.exists()).isTrue(); assertThat(file.isFile()).isTrue(); new JobStorageDatabaseErrorHandler().deleteApi14(context, file); assertThat(file.exists()).isFalse(); }
@Test public void verifyTransientJobNotRescheduled() throws Exception { assertThat(manager().getAllJobRequests()).isEmpty(); Bundle bundle = new Bundle(); bundle.putString("key", "value"); ContentValues contentValues = new JobRequest.Builder("tag") .setExact(TimeUnit.HOURS.toMillis(1)) .setTransientExtras(bundle) .build() .toContentValues(); manager().getJobStorage().getDatabase() .insert(JobStorage.JOB_TABLE_NAME, null, contentValues); Set<JobRequest> requests = manager().getAllJobRequests(); assertThat(requests).isEmpty(); } }
@Test @Config(sdk = 21) public void verifyExactJobRescheduled() throws Exception { assertThat(manager().getAllJobRequests()).isEmpty(); ContentValues contentValues = new JobRequest.Builder("tag") .setExact(TimeUnit.HOURS.toMillis(1)) .build() .toContentValues(); manager().getJobStorage().getDatabase() .insert(JobStorage.JOB_TABLE_NAME, null, contentValues); Set<JobRequest> requests = manager().getAllJobRequests(); assertThat(requests).isNotEmpty(); final int jobId = 1; Intent intent = new Intent(context(), PlatformAlarmReceiver.class); assertThat(PendingIntent.getBroadcast(context(), jobId, intent, PendingIntent.FLAG_NO_CREATE)).isNull(); int rescheduledJobs = new JobRescheduleService().rescheduleJobs(manager()); assertThat(rescheduledJobs).isEqualTo(1); assertThat(PendingIntent.getBroadcast(context(), jobId, intent, PendingIntent.FLAG_NO_CREATE)).isNotNull(); }
@Test @Config(sdk = 21) public void verifyPeriodicJobRescheduled() throws Exception { assertThat(manager().getAllJobRequests()).isEmpty(); ContentValues contentValues = new JobRequest.Builder("tag") .setPeriodic(TimeUnit.HOURS.toMillis(1)) .build() .toContentValues(); manager().getJobStorage().getDatabase() .insert(JobStorage.JOB_TABLE_NAME, null, contentValues); Set<JobRequest> requests = manager().getAllJobRequests(); assertThat(requests).isNotEmpty(); JobScheduler scheduler = (JobScheduler) context().getSystemService(Context.JOB_SCHEDULER_SERVICE); assertThat(scheduler.getAllPendingJobs()).isEmpty(); int rescheduledJobs = new JobRescheduleService().rescheduleJobs(manager()); assertThat(rescheduledJobs).isEqualTo(1); }
public void update(JobRequest request, ContentValues contentValues) { SQLiteDatabase database = null; mLock.writeLock().lock(); try { updateRequestInCache(request); database = getDatabase(); database.update(JOB_TABLE_NAME, contentValues, COLUMN_ID + "=?", new String[]{String.valueOf(request.getJobId())}); } catch (Exception e) { // catch the exception here and keep what's in the database CAT.e(e, "could not update %s", request); } finally { closeDatabase(database); mLock.writeLock().unlock(); } }
private boolean remove(@Nullable JobRequest request, int jobId) { SQLiteDatabase database = null; mLock.writeLock().lock(); try { mCacheId.remove(jobId); database = getDatabase(); database.delete(JOB_TABLE_NAME, COLUMN_ID + "=?", new String[]{String.valueOf(jobId)}); return true; } catch (Exception e) { CAT.e(e, "could not delete %d %s", jobId, request); addFailedDeleteId(jobId); return false; } finally { closeDatabase(database); mLock.writeLock().unlock(); } }
@VisibleForTesting /*package*/ int getMaxJobId() { SQLiteDatabase database = null; Cursor cursor = null; int jobId = 0; try { database = getDatabase(); cursor = database.rawQuery("SELECT MAX(" + COLUMN_ID + ") FROM " + JOB_TABLE_NAME, null); if (cursor != null && cursor.moveToFirst()) { jobId = cursor.getInt(0); } } catch (Exception e) { CAT.e(e); } finally { closeCursor(cursor); closeDatabase(database); } return Math.max(JobConfig.getJobIdOffset(), Math.max(jobId, mPreferences.getInt(JOB_ID_COUNTER, 0))); }
database = getDatabase(); cursor = database.query(JOB_TABLE_NAME, null, where, args, null, null, null);
@SuppressWarnings("SameParameterValue") private JobRequest load(int id, boolean includeStarted) { if (didFailToDelete(id)) { return null; } SQLiteDatabase database = null; Cursor cursor = null; try { String where = COLUMN_ID + "=?"; if (!includeStarted) { where += " AND " + COLUMN_STARTED + "<=0"; } database = getDatabase(); cursor = database.query(JOB_TABLE_NAME, null, where, new String[]{String.valueOf(id)}, null, null, null); if (cursor != null && cursor.moveToFirst()) { return JobRequest.fromCursor(cursor); } } catch (Exception e) { CAT.e(e, "could not load id %d", id); } finally { closeCursor(cursor); closeDatabase(database); } return null; }
private void store(JobRequest request) { ContentValues contentValues = request.toContentValues(); SQLiteDatabase database = null; try { database = getDatabase(); /* * It could happen that a conflict with the job ID occurs, when a job was cancelled (cancelAndEdit()) * the builder object scheduled twice. In this case the last call wins and the value in the database * will be overwritten. */ if (database.insertWithOnConflict(JOB_TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_REPLACE) < 0) { throw new SQLException("Couldn't insert job request into database"); } } finally { closeDatabase(database); } }