private void undoredo(Stack<UndoRow> src, Stack<UndoRow> dst) { UndoRow row; commitToDB(); while (true) { row = src.pop(); if (row != null) break; } Long start = row.start; Long end = row.end; if (end == null) end = latestUndoRow(); ArrayList<String> sql = AnkiDb.queryColumn( String.class, String.format( ENGLISH_LOCALE, "SELECT sql FROM undoLog " + "WHERE seq > %d and seq <= %d " + "ORDER BY seq DESC", start, end), 0); Long newstart = latestUndoRow(); Iterator<String> iter = sql.iterator(); while (iter.hasNext()) AnkiDb.database.execSQL(iter.next()); Long newend = latestUndoRow(); dst.push(new UndoRow(row.name, newstart, newend)); }
public void setUndoStart(String name, boolean merge) { if (!undoEnabled) return; commitToDB(); if (merge && !undoStack.isEmpty()) if ((undoStack.peek() != null) && (undoStack.peek().name.equals(name))) return; undoStack.push(new UndoRow(name, latestUndoRow(), null)); }
public void setUndoEnd(String name) { if (!undoEnabled) return; commitToDB(); long end = latestUndoRow(); while (undoStack.peek() == null) undoStack.pop(); // Strip off barrier UndoRow row = undoStack.peek(); row.end = end; if (row.start == row.end) undoStack.pop(); else redoStack.clear(); }
private void flushMod() { setModified(); commitToDB(); }
public void closeDeck() { DeckTask.waitToFinish(); // Wait for any thread working on the deck to finish. if (modifiedSinceSave()) commitToDB(); AnkiDb.closeDatabase(); }
public static Deck openDeck(String path) throws SQLException { Deck deck = null; Cursor cursor = null; Log.i(TAG, "openDeck - Opening database " + path); AnkiDb.openDatabase(path); try { // Read in deck table columns cursor = AnkiDb.database.rawQuery("SELECT *" + " FROM decks" + " LIMIT 1", null); if (!cursor.moveToFirst()) return null; deck = new Deck(); deck.id = cursor.getLong(0); deck.created = cursor.getDouble(1); deck.modified = cursor.getDouble(2); deck.description = cursor.getString(3); deck.version = cursor.getInt(4); deck.currentModelId = cursor.getLong(5); deck.syncName = cursor.getString(6); deck.lastSync = cursor.getDouble(7); deck.hardIntervalMin = cursor.getDouble(8); deck.hardIntervalMax = cursor.getDouble(9); deck.midIntervalMin = cursor.getDouble(10); deck.midIntervalMax = cursor.getDouble(11); deck.easyIntervalMin = cursor.getDouble(12); deck.easyIntervalMax = cursor.getDouble(13); deck.delay0 = cursor.getDouble(14); deck.delay1 = cursor.getDouble(15); deck.delay2 = cursor.getDouble(16); deck.collapseTime = cursor.getDouble(17); deck.highPriority = cursor.getString(18); deck.medPriority = cursor.getString(19); deck.lowPriority = cursor.getString(20); deck.suspended = cursor.getString(21); deck.newCardOrder = cursor.getInt(22); deck.newCardSpacing = cursor.getInt(23); deck.failedCardMax = cursor.getInt(24); deck.newCardsPerDay = cursor.getInt(25); deck.sessionRepLimit = cursor.getInt(26); deck.sessionTimeLimit = cursor.getInt(27); deck.utcOffset = cursor.getDouble(28); deck.cardCount = cursor.getInt(29); deck.factCount = cursor.getInt(30); deck.failedNowCount = cursor.getInt(31); deck.failedSoonCount = cursor.getInt(32); deck.revCount = cursor.getInt(33); deck.newCount = cursor.getInt(34); deck.revCardOrder = cursor.getInt(35); Log.i(TAG, "openDeck - Read " + cursor.getColumnCount() + " columns from decks table."); } finally { if (cursor != null) cursor.close(); } Log.i( TAG, String.format( ENGLISH_LOCALE, "openDeck - modified: %f currentTime: %f", deck.modified, System.currentTimeMillis() / 1000.0)); deck.initVars(); // Ensure necessary indices are available deck.updateDynamicIndices(); // Save counts to determine if we should save deck after check int oldCount = deck.failedSoonCount + deck.revCount + deck.newCount; // Update counts deck.rebuildQueue(); try { // Unsuspend reviewed early & buried cursor = AnkiDb.database.rawQuery( "SELECT id " + "FROM cards " + "WHERE type in (0,1,2) and " + "isDue = 0 and " + "priority in (-1,-2)", null); if (cursor.moveToFirst()) { int count = cursor.getCount(); long[] ids = new long[count]; for (int i = 0; i < count; i++) { ids[i] = cursor.getLong(0); cursor.moveToNext(); } deck.updatePriorities(ids); deck.checkDue(); } } finally { if (cursor != null) cursor.close(); } // Save deck to database if it has been modified if ((oldCount != (deck.failedSoonCount + deck.revCount + deck.newCount)) || deck.modifiedSinceSave()) deck.commitToDB(); // Create a temporary view for random new cards. Randomizing the cards by themselves // as is done in desktop Anki in Deck.randomizeNewCards() takes too long. AnkiDb.database.execSQL( "CREATE TEMPORARY VIEW acqCardsRandom AS " + "SELECT * FROM cards " + "WHERE type = 2 AND isDue = 1 " + "ORDER BY RANDOM()"); return deck; }
public void redo() { undoredo(redoStack, undoStack); commitToDB(); rebuildCounts(true); }