Search in sources :

Example 6 with ConfirmModSchemaException

use of com.ichi2.anki.exception.ConfirmModSchemaException in project AnkiChinaAndroid by ankichinateam.

the class CollectionTask method doInBackGroundDeleteField.

/**
 * Deletes thje given field in the given model
 */
private TaskData doInBackGroundDeleteField(TaskData param) {
    Timber.d("doInBackGroundDeleteField");
    Object[] objects = param.getObjArray();
    Model model = (Model) objects[0];
    JSONObject field = (JSONObject) objects[1];
    Collection col = getCol();
    try {
        col.getModels().remField(model, field);
        col.save();
    } catch (ConfirmModSchemaException e) {
        // Should never be reached
        return new TaskData(false);
    }
    return new TaskData(true);
}
Also used : JSONObject(com.ichi2.utils.JSONObject) Model(com.ichi2.libanki.Model) TemporaryModel(com.ichi2.anki.TemporaryModel) Collection(com.ichi2.libanki.Collection) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) JSONObject(com.ichi2.utils.JSONObject)

Example 7 with ConfirmModSchemaException

use of com.ichi2.anki.exception.ConfirmModSchemaException in project AnkiChinaAndroid by ankichinateam.

the class Collection method changeSchedulerVer.

public void changeSchedulerVer(Integer ver) throws ConfirmModSchemaException {
    if (ver == schedVer()) {
        return;
    }
    if (!fSupportedSchedulerVersions.contains(ver)) {
        throw new RuntimeException("Unsupported scheduler version");
    }
    modSchema();
    @SuppressLint("VisibleForTests") SchedV2 v2Sched = new SchedV2(this);
    clearUndo();
    if (ver == 1) {
        v2Sched.moveToV1();
    } else {
        v2Sched.moveToV2();
    }
    mConf.put("schedVer", ver);
    setMod();
    _loadScheduler();
}
Also used : SuppressLint(android.annotation.SuppressLint) SchedV2(com.ichi2.libanki.sched.SchedV2)

Example 8 with ConfirmModSchemaException

use of com.ichi2.anki.exception.ConfirmModSchemaException in project AnkiChinaAndroid by ankichinateam.

the class Anki2Importer method _importCards.

private void _importCards() {
    if (mMustResetLearning) {
        try {
            mSrc.changeSchedulerVer(2);
        } catch (ConfirmModSchemaException e) {
            throw new RuntimeException("Changing the scheduler of an import should not cause schema modification", e);
        }
    }
    // build map of guid -> (ord -> cid) and used id cache
    mCards = new HashMap<>();
    Map<Long, Boolean> existing = new HashMap<>();
    Cursor cur = null;
    try {
        cur = mDst.getDb().getDatabase().query("select f.guid, c.ord, c.id from cards c, notes f " + "where c.nid = f.id", null);
        while (cur.moveToNext()) {
            String guid = cur.getString(0);
            int ord = cur.getInt(1);
            long cid = cur.getLong(2);
            existing.put(cid, true);
            if (mCards.containsKey(guid)) {
                mCards.get(guid).put(ord, cid);
            } else {
                Map<Integer, Long> map = new HashMap<>();
                map.put(ord, cid);
                mCards.put(guid, map);
            }
        }
    } finally {
        if (cur != null) {
            cur.close();
        }
    }
    // loop through src
    List<Object[]> cards = new ArrayList<>();
    int totalCardCount = 0;
    final int thresExecCards = 1000;
    List<Object[]> revlog = new ArrayList<>();
    int totalRevlogCount = 0;
    final int thresExecRevlog = 1000;
    int usn = mDst.usn();
    long aheadBy = mSrc.getSched().getToday() - mDst.getSched().getToday();
    try {
        mDst.getDb().getDatabase().beginTransaction();
        cur = mSrc.getDb().getDatabase().query("select f.guid, f.mid, c.* from cards c, notes f " + "where c.nid = f.id", null);
        // Counters for progress updates
        int total = cur.getCount();
        boolean largeCollection = total > 200;
        int onePercent = total / 100;
        int i = 0;
        while (cur.moveToNext()) {
            Object[] card = new Object[] { cur.getString(0), cur.getLong(1), cur.getLong(2), cur.getLong(3), cur.getLong(4), cur.getInt(5), cur.getLong(6), cur.getInt(7), cur.getInt(8), cur.getInt(9), cur.getLong(10), cur.getLong(11), cur.getLong(12), cur.getInt(13), cur.getInt(14), cur.getInt(15), cur.getLong(16), cur.getLong(17), cur.getInt(18), cur.getString(19) };
            String guid = (String) card[0];
            if (mChangedGuids.containsKey(guid)) {
                guid = mChangedGuids.get(guid);
            }
            if (mIgnoredGuids.containsKey(guid)) {
                continue;
            }
            // does the card's note exist in dst col?
            if (!mNotes.containsKey(guid)) {
                continue;
            }
            Object[] dnid = mNotes.get(guid);
            // does the card already exist in the dst col?
            int ord = (Integer) card[5];
            if (mCards.containsKey(guid) && mCards.get(guid).containsKey(ord)) {
                // fixme: in future, could update if newer mod time
                continue;
            }
            // doesn't exist. strip off note info, and save src id for later
            Object[] oc = card;
            card = new Object[oc.length - 2];
            System.arraycopy(oc, 2, card, 0, card.length);
            long scid = (Long) card[0];
            // ensure the card id is unique
            while (existing.containsKey(card[0])) {
                card[0] = (Long) card[0] + 999;
            }
            existing.put((Long) card[0], true);
            // update cid, nid, etc
            card[1] = mNotes.get(guid)[0];
            card[2] = _did((Long) card[2]);
            if (mTopID < 0) {
                mTopID = (long) card[2];
            }
            card[4] = mCol.getTime().intTime();
            card[5] = usn;
            // review cards have a due date relative to collection
            if ((Integer) card[7] == 2 || (Integer) card[7] == 3 || (Integer) card[6] == 2) {
                card[8] = (Long) card[8] - aheadBy;
            }
            // odue needs updating too
            if (((Long) card[14]).longValue() != 0) {
                card[14] = (Long) card[14] - aheadBy;
            }
            // if odid true, convert card from filtered to normal
            if ((Long) card[15] != 0) {
                // odid
                card[15] = 0;
                // odue
                card[8] = card[14];
                card[14] = 0;
                // queue
                if ((Integer) card[6] == 1) {
                    // type
                    card[7] = 0;
                } else {
                    card[7] = card[6];
                }
                // type
                if ((Integer) card[6] == 1) {
                    card[6] = 0;
                }
            }
            cards.add(card);
            // we need to import revlog, rewriting card ids and bumping usn
            try (Cursor cur2 = mSrc.getDb().getDatabase().query("select * from revlog where cid = " + scid, null)) {
                while (cur2.moveToNext()) {
                    Object[] rev = new Object[] { cur2.getLong(0), cur2.getLong(1), cur2.getInt(2), cur2.getInt(3), cur2.getLong(4), cur2.getLong(5), cur2.getLong(6), cur2.getLong(7), cur2.getInt(8) };
                    rev[1] = card[0];
                    rev[2] = mDst.usn();
                    revlog.add(rev);
                }
            }
            i++;
            // apply card changes partially
            if (cards.size() >= thresExecCards) {
                totalCardCount += cards.size();
                insertCards(cards);
                cards.clear();
                Timber.d("add cards: %d", totalCardCount);
            }
            // apply revlog changes partially
            if (revlog.size() >= thresExecRevlog) {
                totalRevlogCount += revlog.size();
                insertRevlog(revlog);
                revlog.clear();
                Timber.d("add revlog: %d", totalRevlogCount);
            }
            if (total != 0 && (!largeCollection || i % onePercent == 0)) {
                publishProgress(100, i * 100 / total, 0);
            }
        }
        publishProgress(100, 100, 0);
        // count total values
        totalCardCount += cards.size();
        totalRevlogCount += revlog.size();
        Timber.d("add cards total:  %d", totalCardCount);
        Timber.d("add revlog total: %d", totalRevlogCount);
        // apply (for last chunk)
        insertCards(cards);
        cards.clear();
        insertRevlog(revlog);
        revlog.clear();
        mLog.add(getRes().getString(R.string.import_complete_count, totalCardCount));
        mDst.getDb().getDatabase().setTransactionSuccessful();
    } finally {
        if (cur != null) {
            cur.close();
        }
        if (mDst.getDb().getDatabase().inTransaction()) {
            try {
                mDst.getDb().getDatabase().endTransaction();
            } catch (Exception e) {
                Timber.w(e);
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Cursor(android.database.Cursor) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) ImportExportException(com.ichi2.anki.exception.ImportExportException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException)

Example 9 with ConfirmModSchemaException

use of com.ichi2.anki.exception.ConfirmModSchemaException in project AnkiChinaAndroid by ankichinateam.

the class Models method renameField.

public void renameField(Model m, JSONObject field, String newName) throws ConfirmModSchemaException {
    mCol.modSchema();
    String pat = String.format("\\{\\{([^{}]*)([:#^/]|[^:#/^}][^:}]*?:|)%s\\}\\}", Pattern.quote(field.getString("name")));
    if (newName == null) {
        newName = "";
    }
    String repl = "{{$1$2" + newName + "}}";
    JSONArray tmpls = m.getJSONArray("tmpls");
    for (int i = 0; i < tmpls.length(); ++i) {
        JSONObject t = tmpls.getJSONObject(i);
        for (String fmt : new String[] { "qfmt", "afmt" }) {
            if (!"".equals(newName)) {
                t.put(fmt, t.getString(fmt).replaceAll(pat, repl));
            } else {
                t.put(fmt, t.getString(fmt).replaceAll(pat, ""));
            }
        }
    }
    field.put("name", newName);
    save(m);
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray)

Example 10 with ConfirmModSchemaException

use of com.ichi2.anki.exception.ConfirmModSchemaException in project AnkiChinaAndroid by ankichinateam.

the class Models method remField.

public void remField(Model m, JSONObject field) throws ConfirmModSchemaException {
    mCol.modSchema();
    JSONArray flds = m.getJSONArray("flds");
    JSONArray flds2 = new JSONArray();
    int idx = -1;
    for (int i = 0; i < flds.length(); ++i) {
        if (field.equals(flds.getJSONObject(i))) {
            idx = i;
            continue;
        }
        flds2.put(flds.getJSONObject(i));
    }
    m.put("flds", flds2);
    int sortf = m.getInt("sortf");
    if (sortf >= m.getJSONArray("flds").length()) {
        m.put("sortf", sortf - 1);
    }
    _updateFieldOrds(m);
    _transformFields(m, new TransformFieldDelete(idx));
    if (idx == sortIdx(m)) {
        // need to rebuild
        mCol.updateFieldCache(Utils.toPrimitive(nids(m)));
    }
    renameField(m, field, null);
}
Also used : JSONArray(com.ichi2.utils.JSONArray)

Aggregations

JSONObject (com.ichi2.utils.JSONObject)39 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)26 JSONArray (com.ichi2.utils.JSONArray)23 Test (org.junit.Test)22 RobolectricTest (com.ichi2.anki.RobolectricTest)14 ConfirmationDialog (com.ichi2.anki.dialogs.ConfirmationDialog)12 Collection (com.ichi2.libanki.Collection)12 Model (com.ichi2.libanki.Model)12 Note (com.ichi2.libanki.Note)8 ArrayList (java.util.ArrayList)8 JSONException (com.ichi2.utils.JSONException)6 HashMap (java.util.HashMap)5 SdkSuppress (androidx.test.filters.SdkSuppress)4 TaskData (com.ichi2.async.TaskData)4 ModelManager (com.ichi2.libanki.ModelManager)4 TextImporter (com.ichi2.libanki.importer.TextImporter)4 Matchers.containsString (org.hamcrest.Matchers.containsString)4 Cursor (android.database.Cursor)3 Uri (android.net.Uri)3 Bundle (android.os.Bundle)3