diff options
Diffstat (limited to 'fbreader/src/migration/Migration_0_11_0.cpp')
| -rw-r--r-- | fbreader/src/migration/Migration_0_11_0.cpp | 544 |
1 files changed, 0 insertions, 544 deletions
diff --git a/fbreader/src/migration/Migration_0_11_0.cpp b/fbreader/src/migration/Migration_0_11_0.cpp deleted file mode 100644 index 144245e..0000000 --- a/fbreader/src/migration/Migration_0_11_0.cpp +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Copyright (C) 2009-2012 Geometer Plus <contact@geometerplus.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <iostream> -#include <iomanip> -#include <ZLTime.h> - -#include <vector> -#include <algorithm> - -#include <ZLFile.h> -#include <ZLStringUtil.h> -#include <ZLUnicodeUtil.h> - -#include "BookInfo.h" -#include "Migration.h" -#include "../options/FBCategoryKey.h" - -#include "../formats/FormatPlugin.h" - -#include "../database/booksdb/BooksDBUtil.h" -#include "../database/booksdb/BooksDB.h" -#include "../library/Book.h" -#include "../library/Tag.h" - -static const std::string BOOK_LIST_GROUP = "BookList"; -static const std::string BOOK_LIST_SIZE = "Size"; -static const std::string BOOK_LIST_PREFIX = "Book"; - -static const std::string CURRENT_STATE_GROUP = "State"; - -static const std::string RECENT_BOOKS_GROUP = "LastOpenedBooks"; -static const std::string BOOK = "Book"; -static const std::size_t MaxXmlListSize = 10; - -static const std::string PARAGRAPH_OPTION_NAME = "Paragraph"; -static const std::string WORD_OPTION_NAME = "Word"; -static const std::string CHAR_OPTION_NAME = "Char"; -static const std::string POSITION_IN_BUFFER = "PositionInBuffer"; -static const std::string BUFFER_SIZE = "UndoBufferSize"; -static const char * const BUFFER_PARAGRAPH_PREFIX = "Paragraph_"; -static const char * const BUFFER_WORD_PREFIX = "Word_"; -static const int MaxXmlStackSize = 20; - -static const std::string SIZE = "Size"; -static const std::string ENTRIES_NUMBER = "EntriesNumber"; -static const std::string PALM_TYPE = "PalmType"; - -static const std::string NET_FILES_GROUP = "Files"; - -class Migration_0_11_0_Runnable : public DBRunnable { - -public: - bool run(); - -private: - bool migrateBooks(); - bool migrateBookList(); - bool migrateState(); - bool migrateNetwork(); - - bool migrateBook(const ZLFile &file); - - std::string tags2string(const TagList &tags); - - bool stringEquals(const std::string &tags1, const std::string &tags2); - - bool migrateRecentBooks(); - - bool migrateBooksState(); - - bool migrateBookStateStack(const std::string &fileName, const Book &book); - bool migrateBookLastState(const std::string &fileName, const Book &book); - - bool shouldReadDisk(const std::string &fileName); - - bool clearBooksOptions(); - - static void moveOption(const ZLCategoryKey &category, const std::string &oldGroup, const std::string &newGroup, const std::string &name, const std::string &defaultValue); - static void moveOption(const ZLCategoryKey &category, const std::string &oldGroup, const std::string &newGroup, const std::string &name, int defaultValue); - static void movePercentGroups(std::vector<std::string> &optionGroups); - static void moveBookGroup(const std::string &oldgroup, const std::string &newgroup); - -private: - std::map<std::string, shared_ptr<Book> > myBooks; -}; - - -inline bool Migration_0_11_0_Runnable::shouldReadDisk(const std::string &fileName) { - const std::string ext = ZLFile(fileName).extension(); - return ext == "fb2" || ext == "epub" || ext == "mobi" || ext == "oebzip" || ext == "opf"; - //return ext == "fb2"; - //return true; -} - - -void Migration_0_11_0_Runnable::moveOption(const ZLCategoryKey &category, const std::string &oldGroup, const std::string &newGroup, const std::string &name, const std::string &defaultValue) { - ZLStringOption newOption(category, newGroup, name, defaultValue); - ZLStringOption oldOption(category, oldGroup, name, defaultValue); - newOption.setValue(oldOption.value()); - oldOption.setValue(defaultValue); -} - -void Migration_0_11_0_Runnable::moveOption(const ZLCategoryKey &category, const std::string &oldGroup, const std::string &newGroup, const std::string &name, int defaultValue) { - ZLIntegerOption newOption(category, newGroup, name, defaultValue); - ZLIntegerOption oldOption(category, oldGroup, name, defaultValue); - newOption.setValue(oldOption.value()); - oldOption.setValue(defaultValue); -} - -static bool percentPathPredicate(const std::string &path) { - static const std::string _start = "%APPLICATION_PATH%"; - return ZLStringUtil::stringStartsWith(path, _start); -} - -void Migration_0_11_0_Runnable::movePercentGroups(std::vector<std::string> &optionGroups) { - std::vector<std::string>::iterator it = optionGroups.begin(); - while ((it = std::find_if(it, optionGroups.end(), percentPathPredicate)) != optionGroups.end()) { - const std::string oldgroup = *it; - const std::string newgroup = ZLFile(oldgroup).resolvedPath(); - if (std::find(optionGroups.begin(), optionGroups.end(), newgroup) == optionGroups.end()) { - moveBookGroup(oldgroup, newgroup); - *it++ = newgroup; - } else { - if (BookInfo(newgroup).TitleOption.value().empty()) { - moveBookGroup(oldgroup, newgroup); - } - it = optionGroups.erase(it); - } - ZLOption::clearGroup(oldgroup); - } -} - -void Migration_0_11_0_Runnable::moveBookGroup(const std::string &oldgroup, const std::string &newgroup) { - BookInfo oldbi(oldgroup); - BookInfo newbi(newgroup); - newbi = oldbi; - oldbi.reset(); - - moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, PARAGRAPH_OPTION_NAME, 0); - moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, WORD_OPTION_NAME, 0); - moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, CHAR_OPTION_NAME, 0); - moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, POSITION_IN_BUFFER, 0); - - int stackSize = ZLIntegerOption(ZLCategoryKey::STATE, oldgroup, BUFFER_SIZE, 0).value(); - for (int i = 0; i < stackSize; ++i) { - std::string bufferParagraph = BUFFER_PARAGRAPH_PREFIX; - std::string bufferWord = BUFFER_WORD_PREFIX; - ZLStringUtil::appendNumber(bufferParagraph, i); - ZLStringUtil::appendNumber(bufferWord, i); - moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, bufferParagraph, -1); - moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, bufferWord, -1); - } - moveOption(ZLCategoryKey::STATE, oldgroup, newgroup, BUFFER_SIZE, 0); -} - - - -Migration_0_11_0::Migration_0_11_0() : Migration("0.11.0") { -} - -void Migration_0_11_0::doMigrationInternal() { - Migration_0_11_0_Runnable r; - BooksDB::Instance().executeAsTransaction(r); - //r.run(); -} - -bool Migration_0_11_0_Runnable::run() { -const ZLTime start; - if (!migrateBooks()) { - std::cerr << std::endl << "VERDICT: migrateBooks failed" << std::endl << std::endl; - } -std::cerr << "migration total 0: " << ZLTime().millisecondsFrom(start) << "ms" << std::endl; - if (!migrateBookList()) { - std::cerr << std::endl << "VERDICT: migrateBookList failed" << std::endl << std::endl; - } -std::cerr << "migration total 1: " << ZLTime().millisecondsFrom(start) << "ms" << std::endl; - if (!migrateState()) { - std::cerr << std::endl << "VERDICT: migrateState failed" << std::endl << std::endl; - } -std::cerr << "migration total 2: " << ZLTime().millisecondsFrom(start) << "ms" << std::endl; - if (!migrateNetwork()) { - std::cerr << std::endl << "VERDICT: migrateNetwork failed" << std::endl << std::endl; - } -std::cerr << "migration total 3: " << ZLTime().millisecondsFrom(start) << "ms" << std::endl; - if (!clearBooksOptions()) { - std::cerr << std::endl << "VERDICT: clearBooksOptions failed" << std::endl << std::endl; - } -std::cerr << "migration total 4: " << ZLTime().millisecondsFrom(start) << "ms" << std::endl; - return true; -} - - - -bool Migration_0_11_0_Runnable::migrateBooks() { - /*std::map<std::string, unsigned long> ext2time; - std::map<std::string, unsigned long> ext2num; - unsigned long totalTime = 0, totalNum = 0;*/ - - PluginCollection &collection = PluginCollection::Instance(); - std::vector<std::string> optionGroups; - ZLOption::listOptionGroups(optionGroups); - - movePercentGroups(optionGroups); - - bool res = true; - for (std::vector<std::string>::const_iterator it = optionGroups.begin(); it != optionGroups.end(); ++it) { - const std::string &name = *it; - if (Migration::isLikeToFileName(name)) { - /* TODO: check correctness of migration order: - * 1) palmType - * 2) size - * 3) book (depends on palmType and size) - */ - const std::string palmType = ZLStringOption(FBCategoryKey::BOOKS, name, PALM_TYPE, "").value(); - if (!palmType.empty()) { - BooksDB::Instance().setPalmType(name, palmType); - } - ZLStringOption(FBCategoryKey::BOOKS, name, PALM_TYPE, "").setValue(""); // clean books.xml - ZLFile file(name); - if (file.physicalFilePath() == name) { - int size = ZLIntegerOption(FBCategoryKey::BOOKS, name, SIZE, -1).value(); - if (size != -1) { - BooksDB::Instance().setFileSize(name, size); - } - } - if (collection.plugin(file, false) != 0) { - if (!BookInfo(name).TitleOption.value().empty()) { - //ZLTime start; - if (!migrateBook(ZLFile(name))) { - std::cerr << "ERROR(2): migrateBook failed" << std::endl; - res = false; - } - /*ZLTime end; - { - unsigned time = end.millisecondsFrom(start); - std::string ext = ZLFile(name).extension(); - totalTime += time; - totalNum += 1; - ext2time[ext] += time; - ext2num[ext] += 1; - }*/ - } - BookInfo(name).reset(); // clean books.xml - } else { - ZLOption::clearGroup(name); // clean books.xml - } - ZLIntegerOption(FBCategoryKey::BOOKS, name, SIZE, -1).setValue(-1); // clean books.xml - if (!ZLStringOption(FBCategoryKey::BOOKS, name, ENTRIES_NUMBER, "").value().empty()) { - ZLOption::clearGroup(name); // clean books.xml - } - } - } - - /*std::cerr << " ext" << " time,ms" << " time/total,%" << " number of books" << " time for 1 book,ms" << std::endl; - std::cerr << "---------------------------------------------------------------------------" << std::endl; - for (std::map<std::string, unsigned long>::const_iterator it = ext2time.begin(); it != ext2time.end(); ++it) { - const std::string &ext = it->first; - unsigned long time = it->second; - unsigned long num = ext2num[ext]; - std::cerr << std::setw(8) << ext << std::setw(10) << time << std::setw(15) << ((float) time) / totalTime * 100.0 - << std::setw(18) << num << std::setw(22) << ((float) time) / num << std::endl; - } - std::cerr << "---------------------------------------------------------------------------" << std::endl; - std::cerr << "total:" << std::endl; - std::cerr << std::setw(8) << "" << std::setw(10) << totalTime << std::setw(15) << "" - << std::setw(20) << totalNum << std::setw(20) << "" << std::endl;*/ - - return res; -} - - -bool Migration_0_11_0_Runnable::migrateBook(const ZLFile &file) { - shared_ptr<Book> infoBook = Book::loadFromBookInfo(file); - if (infoBook.isNull()) { - std::cerr << "ERROR: loading book from BookInfo failed: " << file.path() << std::endl; - return false; - } - if (shouldReadDisk(file.path()) && BooksDBUtil::isBookFull(*infoBook)) { - shared_ptr<Book> fileBook = Book::loadFromFile(file); - //shared_ptr<Book> fileBook = infoBook; - //shared_ptr<Book> fileBook; - if (!fileBook.isNull()) { - std::string tagList1 = tags2string(infoBook->tags()); - std::string tagList2 = tags2string(fileBook->tags()); - if (stringEquals(tagList1, tagList2)) { - infoBook->removeAllTags(); - const TagList &tList = fileBook->tags(); - for (TagList::const_iterator it = tList.begin(); it != tList.end(); ++it) { - infoBook->addTag(*it); - } - } - } - } - myBooks.insert(std::make_pair(file.path(), infoBook)); - const bool code = BooksDB::Instance().saveBook(infoBook); - if (!code) { - std::cerr << "ERROR: saving book to database failed: " << file.path() << std::endl; - } - return code; -} - -std::string Migration_0_11_0_Runnable::tags2string(const TagList &tags) { - std::string tagList; - TagList::const_iterator it = tags.begin(); - if (it != tags.end()) { - tagList += (*it++)->fullName(); - while (it != tags.end()) { - tagList += ','; - tagList += (*it++)->fullName(); - } - } - return tagList; -} - -bool Migration_0_11_0_Runnable::stringEquals(const std::string &tags1, const std::string &tags2) { - std::size_t i1 = 0; - std::size_t i2 = 0; - while (i1 < tags1.size() && i2 < tags2.size()) { - if (std::isspace(tags1[i1])) { - ++i1; - continue; - } - if (std::isspace(tags2[i2])) { - ++i2; - continue; - } - if (tags1[i1++] != tags2[i2++]) { - return false; - } - } - if (i1 == tags1.size() && i2 < tags2.size()) { - while (i2 < tags2.size()) { - if (!std::isspace(tags2[i2++])) { - return false; - } - } - return true; - } - if (i1 < tags1.size() && i2 == tags2.size()) { - while (i1 < tags1.size()) { - if (!std::isspace(tags1[i1++])) { - return false; - } - } - return true; - } - return true; -} - -bool Migration_0_11_0_Runnable::migrateBookList() { - bool res = true; - int size = ZLIntegerOption(ZLCategoryKey::STATE, BOOK_LIST_GROUP, BOOK_LIST_SIZE, 0).value(); - for (int i = 0; i < size; ++i) { - std::string optionName = BOOK_LIST_PREFIX; - ZLStringUtil::appendNumber(optionName, i); - const std::string &fileName = ZLStringOption(ZLCategoryKey::STATE, BOOK_LIST_GROUP, optionName, "").value(); - if (!fileName.empty()) { - std::map<std::string, shared_ptr<Book> >::iterator it = myBooks.find(fileName); - if (it != myBooks.end()) { - shared_ptr<Book> book = it->second; - if (!book.isNull() && book->bookId() != 0) { - if (!BooksDB::Instance().insertIntoBookList(*book)) { - std::cerr << "ERROR: insert into BookList failed: " << fileName << std::endl; - res = false; - } - } - } - } - } - ZLOption::clearGroup(BOOK_LIST_GROUP); // clean state.xml - return res; -} - -bool Migration_0_11_0_Runnable::migrateState() { - bool res = true; - if (!migrateRecentBooks()) { - std::cerr << "ERROR(2): migrateRecentBooks failed" << std::endl; - res = false; - } - if (!migrateBooksState()) { - std::cerr << "ERROR(2): migrateBooksState failed" << std::endl; - res = false; - } - ZLOption::clearGroup(RECENT_BOOKS_GROUP); // clean state.xml - ZLOption::clearGroup(CURRENT_STATE_GROUP); // clean state.xml - return res; -} - -bool Migration_0_11_0_Runnable::migrateRecentBooks() { - BookList books; - for (std::size_t i = 0; i < MaxXmlListSize; ++i) { - std::string num = BOOK; - ZLStringUtil::appendNumber(num, i); - std::string name = ZLStringOption(ZLCategoryKey::STATE, RECENT_BOOKS_GROUP, num, "").value(); - if (!name.empty()) { - //shared_ptr<Book> book = BooksDBUtil::getBook(name, false); - std::map<std::string, shared_ptr<Book> >::const_iterator it = myBooks.find(name); - if (it == myBooks.end()) { - if ((it = myBooks.find(ZLFile(name).resolvedPath())) == myBooks.end()) { - continue; - } - } - shared_ptr<Book> book = it->second; - if (!book.isNull() && book->bookId() != 0 && std::find(books.begin(), books.end(), book) == books.end()) { - books.push_back(book); - } - } - } - bool res = BooksDB::Instance().saveRecentBooks(books); - if (!res) { - std::cerr << "ERROR: saving recent books list failed (" << books.size() << " item[s])" << std::endl; - } - return res; -} - -bool Migration_0_11_0_Runnable::migrateBooksState() { - bool res = true; - - for (std::map<std::string, shared_ptr<Book> >::const_iterator it = myBooks.begin(); it != myBooks.end(); ++it) { - const std::string &fileName = it->first; - if (it->second.isNull()) { - std::cerr << "ERROR: book in map is null: " << fileName << std::endl; - res = false; - continue; - } - const Book &book = *it->second; - if (!migrateBookStateStack(fileName, book)) { - res = false; - } - if (!migrateBookLastState(fileName, book)) { - res = false; - } - } - return res; -} - - -bool Migration_0_11_0_Runnable::migrateBookStateStack(const std::string &fileName, const Book &book) { - std::deque<ReadingState> stack; - bool res = true; - int stackSize = ZLIntegerOption(ZLCategoryKey::STATE, fileName, BUFFER_SIZE, 0).value(); - if (stackSize > 0) { - if (stackSize > MaxXmlStackSize) { - stackSize = MaxXmlStackSize; - } - for (int i = 0; i < stackSize; ++i) { - std::string bufferParagraph = BUFFER_PARAGRAPH_PREFIX; - std::string bufferWord = BUFFER_WORD_PREFIX; - ZLStringUtil::appendNumber(bufferParagraph, i); - ZLStringUtil::appendNumber(bufferWord, i); - ReadingState pos( - ZLIntegerOption(ZLCategoryKey::STATE, fileName, bufferParagraph, -1).value(), - ZLIntegerOption(ZLCategoryKey::STATE, fileName, bufferWord, -1).value(), - 0 - ); - stack.push_back(pos); - ZLIntegerOption(ZLCategoryKey::STATE, fileName, bufferParagraph, -1).setValue(-1); // clean state.xml - ZLIntegerOption(ZLCategoryKey::STATE, fileName, bufferWord, -1).setValue(-1); // clean state.xml - } - if (!BooksDB::Instance().saveBookStateStack(book, stack)) { - std::cerr << "ERROR: saving book state stack failed: " << fileName << std::endl; - res = false; - } - stack.clear(); - } - ZLIntegerOption(ZLCategoryKey::STATE, fileName, BUFFER_SIZE, 0).setValue(0); // clean state.xml - return res; -} - -bool Migration_0_11_0_Runnable::migrateBookLastState(const std::string &fileName, const Book &book) { - const ReadingState state( - ZLIntegerOption(ZLCategoryKey::STATE, fileName, PARAGRAPH_OPTION_NAME, 0).value(), - ZLIntegerOption(ZLCategoryKey::STATE, fileName, WORD_OPTION_NAME, 0).value(), - ZLIntegerOption(ZLCategoryKey::STATE, fileName, CHAR_OPTION_NAME, 0).value() - ); - const int stackPos = ZLIntegerOption(ZLCategoryKey::STATE, fileName, POSITION_IN_BUFFER, 0).value(); - if (state.Paragraph == 0 && state.Word == 0 && state.Character == 0 && stackPos == 0) { - return true; - } - ZLIntegerOption(ZLCategoryKey::STATE, fileName, PARAGRAPH_OPTION_NAME, 0).setValue(0); - ZLIntegerOption(ZLCategoryKey::STATE, fileName, WORD_OPTION_NAME, 0).setValue(0); - ZLIntegerOption(ZLCategoryKey::STATE, fileName, CHAR_OPTION_NAME, 0).setValue(0); - ZLIntegerOption(ZLCategoryKey::STATE, fileName, POSITION_IN_BUFFER, 0).setValue(0); - bool res1 = BooksDB::Instance().setBookState(book, state); - bool res2 = BooksDB::Instance().setStackPos(book, stackPos); - if (!res1) { - std::cerr << "ERROR: saving book last state failed: " << fileName << std::endl; - } - if (!res2) { - std::cerr << "ERROR: saving book state stack position failed: " << fileName << std::endl; - } - return res1 && res2; -} - -bool Migration_0_11_0_Runnable::migrateNetwork() { - bool res = true; -// FBReader desktop 0.99.1 deprecates NetFiles table, so don't fill it -// std::vector<std::string> urls; -// ZLOption::listOptionNames(NET_FILES_GROUP, urls); -// for (std::vector<std::string>::const_iterator it = urls.begin(); it != urls.end(); ++it) { -// const std::string &url = *it; -// const std::string fileName = ZLStringOption(ZLCategoryKey::NETWORK, NET_FILES_GROUP, url, "").value(); -// if (!BooksDB::Instance().setNetFile(url, fileName)) { -// std::cerr << "ERROR: saving file's URL failed: " << std::endl -// << "\tURL = " << url << std::endl -// << "\tfileName = " << fileName << std::endl; -// res = false; -// } -// } - ZLOption::clearGroup(NET_FILES_GROUP); // clean state.xml - return res; -} - -bool Migration_0_11_0_Runnable::clearBooksOptions() { - bool res = true; - for (std::map<std::string, shared_ptr<Book> >::const_iterator it = myBooks.begin(); it != myBooks.end(); ++it) { - const std::string &fileName = it->first; - if (it->second.isNull()) { - std::cerr << "ERROR: book in map is null in clearBooksOptions: " << fileName << std::endl; - res = false; - continue; - } - ZLOption::clearGroup(fileName); // clear books.xml & state.xml - } - return res; -} - |
