public Anki2Importer(Collection collection, StorageFolder sourceFolder, string relativePathToFile) : base(collection, sourceFolder, relativePathToFile) { needMapper = false; deckPrefix = null; isAllowUpdate = new DuplicateNoteUpdate(); dupeOnSchemaChange = false; importedNoteId = new List <long>(); importedDeckIdMap = new Dictionary <long, long>(); }
private async Task ImportNotes() { // build guid -> (id,mod,mid) hash & map of existing note ids notes = new Dictionary <string, object[]>(); Dictionary <long, bool> existing = new Dictionary <long, bool>(); var list = destCol.Database.QueryColumn <NoteTable>("select id, guid, mod, mid from notes"); foreach (NoteTable n in list) { long id = n.Id; string guid = n.GuId; long mod = n.TimeModified; long mid = n.Mid; notes.Add(guid, new object[] { id, mod, mid }); existing.Add(id, true); } // we may need to rewrite the guid if the model schemas don't match, // so we need to keep track of the changes for the card import stage changedGuids = new Dictionary <string, string>(); // apart from upgrading from anki1 decks, we ignore updates to changed // schemas. we need to note the ignored guids, so we avoid importing // invalid cards ignoredGuids = new Dictionary <string, bool>(); // iterate over source collection List <object[]> add = new List <object[]>(); List <object[]> update = new List <object[]>(); List <long> dirty = new List <long>(); int usn = destCol.Usn; int dupes = 0; List <string> dupesIgnored = new List <string>(); list = sourceCol.Database.QueryColumn <NoteTable>("select * from notes"); bool largeCollection = total > 200; int i = 0; foreach (NoteTable nl in list) { bool shouldAdd = UniquifyNote(nl); // turn the db result into a mutable list object[] note = new object[] { nl.Id, nl.GuId, nl.Mid, nl.TimeModified, nl.Usn, nl.Tags, nl.Fields, nl.Sortfields, nl.CheckSum, nl.Flags, nl.Data }; if (shouldAdd) { // ensure id is unique while (existing.ContainsKey(nl.Id)) { nl.Id = nl.Id + 999; } existing.Add(nl.Id, true); note[0] = nl.Id; // bump usn note[4] = usn; //WARNING: in ankiU media files are store in their //deckId folder so we simply replace exising files //with imported files if they have the same same //// update media references in case of dupes //note[6] = await MungeMedia(nl.Mid, nl.Fields); note[6] = nl.Fields; add.Add(note); dirty.Add(nl.Id); // note we have the added guid notes.Add(nl.GuId, new object[] { note[0], note[3], note[MID] }); } else { // a duplicate or changed schema - safe to update? dupes += 1; if (!isAllowUpdate.isNotAskAgain) { if (DuplicateNoteEvent != null) { isAllowUpdate = await DuplicateNoteEvent(); } } if (isAllowUpdate.isAllow) { object[] n = notes[nl.GuId]; long oldNid = Convert.ToInt64(n[0]); long oldMod = Convert.ToInt64(n[1]); long oldMid = Convert.ToInt64(n[2]); // will update if incoming note more recent if (oldMod < nl.TimeModified) { // safe if note types identical if (oldMid == nl.Mid) { // incoming note should use existing id note[0] = oldNid; note[4] = usn; //WARNING: in ankiU media files are store in their //deckId folder so we simply replace exising files //with imported files if they have the same same //// update media references in case of dupes //note[6] = await MungeMedia(nl.Mid, nl.Fields); note[6] = nl.Fields; update.Add(note); dirty.Add(oldNid); } else { dupesIgnored.Add(String.Format("{0}: {1}", destCol.Models.Get(oldMid).GetNamedString("name"), (nl.Fields).Replace("\u001f", ","))); ignoredGuids.Add(nl.GuId, true); } } } } i++; } // export info for calling code this.dupes = dupes; added = add.Count; updated = update.Count; // add to col //Don't use excute many here as we've already call RunInTransaction in Import foreach (var c in add) { //Only in AnkU we will need this ID to move media files after importing importedNoteId.Add((long)c[0]); destCol.Database.Execute("insert or replace into notes values (?,?,?,?,?,?,?,?,?,?,?)", c); } foreach (var u in update) { //Only in AnkU we will need this ID to move media files after importing importedNoteId.Add((long)u[0]); destCol.Database.Execute("insert or replace into notes values (?,?,?,?,?,?,?,?,?,?,?)", u); } long[] das = dirty.ToArray(); destCol.UpdateFieldCache(das); destCol.Tags.RegisterNotes(das); }