Search in sources :

Example 26 with AbstractSched

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);
}
Also used : AbstractSched(com.ichi2.libanki.sched.AbstractSched) Collection(com.ichi2.libanki.Collection) Card(com.ichi2.libanki.Card)

Example 27 with AbstractSched

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);
}
Also used : Undoable(com.ichi2.libanki.Undoable) AbstractSched(com.ichi2.libanki.sched.AbstractSched) ArrayList(java.util.ArrayList) Card(com.ichi2.libanki.Card) Note(com.ichi2.libanki.Note) Collection(com.ichi2.libanki.Collection) JSONObject(com.ichi2.utils.JSONObject)

Example 28 with AbstractSched

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;
}
Also used : AbstractSched(com.ichi2.libanki.sched.AbstractSched) AbstractSched(com.ichi2.libanki.sched.AbstractSched) Sched(com.ichi2.libanki.sched.Sched) SchedV2(com.ichi2.libanki.sched.SchedV2)

Example 29 with AbstractSched

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);
}
Also used : AbstractSched(com.ichi2.libanki.sched.AbstractSched) Collection(com.ichi2.libanki.Collection) Cursor(android.database.Cursor) Card(com.ichi2.libanki.Card) Test(org.junit.Test)

Example 30 with AbstractSched

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);
    }
}
Also used : JSONObject(com.ichi2.utils.JSONObject) AbstractSched(com.ichi2.libanki.sched.AbstractSched) JSONArray(com.ichi2.utils.JSONArray) Deck(com.ichi2.libanki.Deck) JSONException(com.ichi2.utils.JSONException) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

Card (com.ichi2.libanki.Card)28 Collection (com.ichi2.libanki.Collection)28 Test (org.junit.Test)23 AbstractSched (com.ichi2.libanki.sched.AbstractSched)19 RobolectricTest (com.ichi2.anki.RobolectricTest)18 Note (com.ichi2.libanki.Note)12 DeckConfig (com.ichi2.libanki.DeckConfig)9 JSONObject (com.ichi2.utils.JSONObject)9 Deck (com.ichi2.libanki.Deck)5 JSONArray (com.ichi2.utils.JSONArray)5 Cursor (android.database.Cursor)4 DB (com.ichi2.libanki.DB)4 Model (com.ichi2.libanki.Model)4 Matchers.containsString (org.hamcrest.Matchers.containsString)4 Models (com.ichi2.libanki.Models)3 Undoable (com.ichi2.libanki.Undoable)3 Sched (com.ichi2.libanki.sched.Sched)3 SchedV2 (com.ichi2.libanki.sched.SchedV2)3 JSONException (com.ichi2.utils.JSONException)3 SuppressLint (android.annotation.SuppressLint)2