use of com.ichi2.libanki.DB in project AnkiChinaAndroid by ankichinateam.
the class Collection method basicCheck.
/**
* DB maintenance *********************************************************** ************************************
*/
/*
* Basic integrity check for syncing. True if ok.
*/
public boolean basicCheck() {
// cards without notes
if (mDb.queryScalar("select 1 from cards where nid not in (select id from notes) limit 1") > 0) {
return false;
}
boolean badNotes = mDb.queryScalar("select 1 from notes where id not in (select distinct nid from cards) " + "or mid not in " + Utils.ids2str(getModels().ids()) + " limit 1") > 0;
// notes without cards or models
if (badNotes) {
return false;
}
// invalid ords
for (JSONObject m : getModels().all()) {
// ignore clozes
if (m.getInt("type") != Consts.MODEL_STD) {
continue;
}
// Make a list of valid ords for this model
JSONArray tmpls = m.getJSONArray("tmpls");
boolean badOrd = mDb.queryScalar("select 1 from cards where (ord < 0 or ord >= ?) and nid in ( " + "select id from notes where mid = ?) limit 1", tmpls.length(), m.getLong("id")) > 0;
if (badOrd) {
return false;
}
}
return true;
}
use of com.ichi2.libanki.DB in project AnkiChinaAndroid by ankichinateam.
the class Collection method load.
/**
* DB-related *************************************************************** ********************************
*/
public void load() {
Cursor cursor = null;
String deckConf = "";
try {
// Read in deck table columns
cursor = mDb.query("SELECT crt, mod, scm, dty, usn, ls, " + "conf, dconf, tags,ver FROM col");
if (!cursor.moveToFirst()) {
return;
}
mCrt = cursor.getLong(0);
mMod = cursor.getLong(1);
mScm = cursor.getLong(2);
// No longer used
mDty = cursor.getInt(3) == 1;
mUsn = cursor.getInt(4);
mLs = cursor.getLong(5);
mConf = new JSONObject(cursor.getString(6));
deckConf = cursor.getString(7);
mTagsJson = cursor.getString(8);
mTags.load(mTagsJson);
mVer = cursor.getInt(9);
} finally {
if (cursor != null) {
cursor.close();
}
}
// getModels().load(loadColumn("models")); This code has been
// moved to `CollectionHelper::loadLazyCollection` for
// efficiency Models are loaded lazily on demand. The
// application layer can asynchronously pre-fetch those parts;
// otherwise they get loaded when required.
Timber.i("load new collection");
mDecks.load(loadColumn("decks"), deckConf);
}
use of com.ichi2.libanki.DB in project AnkiChinaAndroid by ankichinateam.
the class Sched method _fillRev.
@Override
protected boolean _fillRev(boolean allowSibling) {
if (!mRevQueue.isEmpty()) {
return true;
}
if (mRevCount == 0) {
return false;
}
SupportSQLiteDatabase db = mCol.getDb().getDatabase();
while (!mRevDids.isEmpty()) {
long did = mRevDids.getFirst();
int lim = Math.min(mQueueLimit, _deckRevLimit(did));
Cursor cur = null;
if (lim != 0) {
mRevQueue.clear();
// fill the queue with the current did
try {
/* Difference with upstream: we take current card into account.
*
* When current card is answered, the card is not due anymore, so does not belong to the queue.
* Furthermore, _burySiblings ensure that the siblings of the current cards are removed from the
* queue to ensure same day spacing. We simulate this action by ensuring that those siblings are not
* filled, except if we know there are cards and we didn't find any non-sibling card. This way, the
* queue is not empty if it should not be empty (important for the conditional belows), but the
* front of the queue contains distinct card.
*/
String idName = (allowSibling) ? "id" : "nid";
long id = (allowSibling) ? currentCardId() : currentCardNid();
cur = db.query("SELECT id FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_REV + " AND due <= ?" + " AND " + idName + " != ? LIMIT ?", new Object[] { did, mToday, id, lim });
while (cur.moveToNext()) {
mRevQueue.add(cur.getLong(0));
}
} finally {
if (cur != null && !cur.isClosed()) {
cur.close();
}
}
if (!mRevQueue.isEmpty()) {
// ordering
if (mCol.getDecks().get(did).getInt("dyn") != 0) {
// dynamic decks need due order preserved
// Note: libanki reverses mRevQueue and returns the last element in _getRevCard().
// AnkiDroid differs by leaving the queue intact and returning the *first* element
// in _getRevCard().
} else {
Random r = new Random();
r.setSeed(mToday);
mRevQueue.shuffle(r);
}
// is the current did empty?
if (mRevQueue.size() < lim) {
mRevDids.remove();
}
return true;
}
}
// nothing left in the deck; move to next
mRevDids.remove();
}
// Since we didn't get a card and the count is non-zero, we
// need to check again for any cards that were removed from
// the queue but not buried
_resetRev();
return _fillRev(true);
}
use of com.ichi2.libanki.DB in project AnkiChinaAndroid by ankichinateam.
the class Storage method tableMatch.
private static boolean tableMatch(DB db, String tableName, String[] columnNames) {
tableName = tableName.toLowerCase();
String sql = String.format("PRAGMA table_info('%s')", tableName);
try (Cursor cursor = db.getDatabase().query(sql, null)) {
if (cursor.getCount() == columnNames.length) {
int i = 0;
while (cursor.moveToNext()) {
if (!columnNames[i].equals(cursor.getString(cursor.getColumnIndex("name")))) {
return false;
}
i++;
}
return true;
}
} catch (Exception exception) {
exception.printStackTrace();
}
return false;
}
use of com.ichi2.libanki.DB in project AnkiChinaAndroid by ankichinateam.
the class Storage method Collection.
public static Collection Collection(Context context, String path, boolean server, boolean log, @NonNull Time time) {
assert path.endsWith(".anki2");
File dbFile = new File(path);
boolean create = !dbFile.exists();
// // connect
DB db = new DB(path);
try {
// initialize
int ver;
Timber.i("new collection:%s", create);
if (create) {
AnkiDroidApp.getSharedPrefs(context).edit().remove(Consts.KEY_SYNC_CHINA_SESSION).apply();
ver = _createDB(db, time);
} else {
ver = _upgradeSchema(db, time);
}
db.execute("PRAGMA temp_store = memory");
// add db to col and do any remaining upgrades
Collection col = new Collection(context, db, path, server, log, time);
if (ver < Consts.SCHEMA_VERSION) {
AnkiDroidApp.getSharedPrefs(context).edit().remove(Consts.KEY_SYNC_CHINA_SESSION).apply();
_upgrade(col, ver);
} else if (ver > Consts.SCHEMA_VERSION) {
if (ver == 12 && _isVer11(db)) {
// 判断数据库版本是否有问题
db.execute("UPDATE col SET ver = 11");
} else {
throw new RuntimeException("This file requires a newer version of Anki.");
}
} else if (create) {
// add in reverse order so basic is default
for (int i = StdModels.stdModels.length - 1; i >= 0; i--) {
StdModels.stdModels[i].add(col);
}
col.save();
}
return col;
} catch (Exception e) {
Timber.e(e, "Error opening collection; closing database");
db.close();
throw e;
}
}
Aggregations