use of com.ichi2.libanki.sched.AbstractSched in project AnkiChinaAndroid by ankichinateam.
the class CollectionTask method doInBackgroundUndo.
private TaskData doInBackgroundUndo() {
Collection col = getCol();
AbstractSched sched = col.getSched();
try {
col.getDb().getDatabase().beginTransaction();
try {
Card card = nonTaskUndo(col);
publishProgress(new TaskData(card, 0));
col.getDb().getDatabase().setTransactionSuccessful();
} finally {
col.getDb().getDatabase().endTransaction();
}
} catch (RuntimeException e) {
Timber.e(e, "doInBackgroundUndo - RuntimeException on undoing");
AnkiDroidApp.sendExceptionReport(e, "doInBackgroundUndo");
return new TaskData(false);
}
return new TaskData(true);
}
use of com.ichi2.libanki.sched.AbstractSched in project AnkiChinaAndroid by ankichinateam.
the class CollectionTask method doInBackgroundDismissNote.
private TaskData doInBackgroundDismissNote(TaskData param) {
Collection col = getCol();
AbstractSched sched = col.getSched();
Object[] data = param.getObjArray();
Card card = (Card) data[0];
Collection.DismissType type = (Collection.DismissType) data[1];
Note note = card.note();
try {
col.getDb().getDatabase().beginTransaction();
try {
sched.deferReset();
switch(type) {
case BURY_CARD:
// collect undo information
Undoable buryCard = revertToProvidedState(BURY_CARD, card);
col.markUndo(buryCard);
// then bury
sched.buryCards(new long[] { card.getId() });
break;
case BURY_NOTE:
// collect undo information
Undoable buryNote = revertToProvidedState(BURY_NOTE, card);
col.markUndo(buryNote);
// then bury
sched.buryNote(note.getId());
break;
case SUSPEND_CARD:
// collect undo information
Card suspendedCard = card.clone();
Undoable suspendCard = new UndoSuspendCard(suspendedCard);
col.markUndo(suspendCard);
// suspend card
if (card.getQueue() == Consts.QUEUE_TYPE_SUSPENDED) {
sched.unsuspendCards(new long[] { card.getId() });
} else {
sched.suspendCards(new long[] { card.getId() });
}
break;
case SUSPEND_NOTE:
{
// collect undo information
ArrayList<Card> cards = note.cards();
long[] cids = new long[cards.size()];
for (int i = 0; i < cards.size(); i++) {
cids[i] = cards.get(i).getId();
}
col.markUndo(revertToProvidedState(SUSPEND_NOTE, card));
// suspend note
sched.suspendCards(cids);
break;
}
case DELETE_NOTE:
{
// collect undo information
ArrayList<Card> allCs = note.cards();
Undoable deleteNote = new UndoDeleteNote(note, allCs, card);
col.markUndo(deleteNote);
// delete note
col.remNotes(new long[] { note.getId() });
break;
}
}
// With sHadCardQueue set, getCard() resets the scheduler prior to getting the next card
publishProgress(new TaskData(col.getSched().getCard(), 0));
col.getDb().getDatabase().setTransactionSuccessful();
} finally {
col.getDb().getDatabase().endTransaction();
}
} catch (RuntimeException e) {
Timber.e(e, "doInBackgroundDismissNote - RuntimeException on dismissing note, dismiss type %s", type);
AnkiDroidApp.sendExceptionReport(e, "doInBackgroundDismissNote");
return new TaskData(false);
}
return new TaskData(true);
}
use of com.ichi2.libanki.sched.AbstractSched in project AnkiChinaAndroid by ankichinateam.
the class RobolectricTest method upgradeToSchedV2.
protected SchedV2 upgradeToSchedV2() {
getCol().getConf().put("schedVer", 2);
getCol().setMod();
CollectionHelper.getInstance().closeCollection(true, "upgradeToSchedV2");
AbstractSched sched = getCol().getSched();
// Sched inherits from schedv2...
assertThat("sched should be v2", !(sched instanceof Sched));
return (SchedV2) sched;
}
use of com.ichi2.libanki.sched.AbstractSched in project AnkiChinaAndroid by ankichinateam.
the class ContentProviderTest method testQueryNextCard.
/**
* Test that query for the next card in the schedule returns a valid result without any deck selector
*/
@Test
public void testQueryNextCard() {
Collection col = getCol();
AbstractSched sched = col.getSched();
Cursor reviewInfoCursor = InstrumentationRegistry.getInstrumentation().getTargetContext().getContentResolver().query(FlashCardsContract.ReviewInfo.CONTENT_URI, null, null, null, null);
assertNotNull(reviewInfoCursor);
assertEquals("Check that we actually received one card", 1, reviewInfoCursor.getCount());
reviewInfoCursor.moveToFirst();
int cardOrd = reviewInfoCursor.getInt(reviewInfoCursor.getColumnIndex(FlashCardsContract.ReviewInfo.CARD_ORD));
long noteID = reviewInfoCursor.getLong(reviewInfoCursor.getColumnIndex(FlashCardsContract.ReviewInfo.NOTE_ID));
Card nextCard = null;
for (int i = 0; i < 10; i++) {
// minimizing fails, when sched.reset() randomly chooses between multiple cards
col.reset();
nextCard = sched.getCard();
if (nextCard.note().getId() == noteID && nextCard.getOrd() == cardOrd)
break;
}
assertNotNull("Check that there actually is a next scheduled card", nextCard);
assertEquals("Check that received card and actual card have same note id", nextCard.note().getId(), noteID);
assertEquals("Check that received card and actual card have same card ord", nextCard.getOrd(), cardOrd);
}
use of com.ichi2.libanki.sched.AbstractSched in project AnkiChinaAndroid by ankichinateam.
the class Syncer method sanityCheck.
public JSONObject sanityCheck() {
JSONObject result = new JSONObject();
try {
if (mCol.getDb().queryScalar("SELECT count() FROM cards WHERE nid NOT IN (SELECT id FROM notes)") != 0) {
Timber.e("Sync - SanityCheck: there are cards without mother notes");
result.put("client", "missing notes");
return result;
}
if (mCol.getDb().queryScalar("SELECT count() FROM notes WHERE id NOT IN (SELECT DISTINCT nid FROM cards)") != 0) {
Timber.e("Sync - SanityCheck: there are notes without cards");
result.put("client", "missing cards");
return result;
}
if (mCol.getDb().queryScalar("SELECT count() FROM cards WHERE usn = -1") != 0) {
Timber.e("Sync - SanityCheck: there are unsynced cards");
result.put("client", "cards had usn = -1");
return result;
}
if (mCol.getDb().queryScalar("SELECT count() FROM notes WHERE usn = -1") != 0) {
Timber.e("Sync - SanityCheck: there are unsynced notes");
result.put("client", "notes had usn = -1");
return result;
}
if (mCol.getDb().queryScalar("SELECT count() FROM revlog WHERE usn = -1") != 0) {
Timber.e("Sync - SanityCheck: there are unsynced revlogs");
result.put("client", "revlog had usn = -1");
return result;
}
if (mCol.getDb().queryScalar("SELECT count() FROM graves WHERE usn = -1") != 0) {
Timber.e("Sync - SanityCheck: there are unsynced graves");
result.put("client", "graves had usn = -1");
return result;
}
for (Deck g : mCol.getDecks().all()) {
if (g.getInt("usn") == -1) {
Timber.e("Sync - SanityCheck: unsynced deck: " + g.getString("name"));
result.put("client", "deck had usn = -1");
return result;
}
}
for (Map.Entry<String, Integer> tag : mCol.getTags().allItems()) {
if (tag.getValue() == -1) {
Timber.e("Sync - SanityCheck: there are unsynced tags");
result.put("client", "tag had usn = -1");
return result;
}
}
boolean found = false;
for (JSONObject m : mCol.getModels().all()) {
if (mCol.getServer()) {
// the web upgrade was mistakenly setting usn
if (m.getInt("usn") < 0) {
m.put("usn", 0);
found = true;
}
} else {
if (m.getInt("usn") == -1) {
Timber.e("Sync - SanityCheck: unsynced model: " + m.getString("name"));
result.put("client", "model had usn = -1");
return result;
}
}
}
if (found) {
mCol.getModels().save();
}
// check for missing parent decks
mCol.getSched().deckDueList();
// return summary of deck
JSONArray check = new JSONArray();
JSONArray counts = new JSONArray();
// #5666 - not in libAnki
// We modified mReportLimit inside the scheduler, and this causes issues syncing dynamic decks.
AbstractSched syncScheduler = mCol.createScheduler(SYNC_SCHEDULER_REPORT_LIMIT);
for (int c : syncScheduler.recalculateCounts()) {
counts.put(c);
}
check.put(counts);
check.put(mCol.getDb().queryScalar("SELECT count() FROM cards"));
check.put(mCol.getDb().queryScalar("SELECT count() FROM notes"));
check.put(mCol.getDb().queryScalar("SELECT count() FROM revlog"));
check.put(mCol.getDb().queryScalar("SELECT count() FROM graves"));
check.put(mCol.getModels().all().size());
check.put(mCol.getDecks().all().size());
check.put(mCol.getDecks().allConf().size());
result.put("client", check);
return result;
} catch (JSONException e) {
Timber.e(e, "Syncer.sanityCheck()");
throw new RuntimeException(e);
}
}
Aggregations