/// TODO, need a better way to identify the file. /// Lookup the file name. /// Check the location. /// File content hash. (Which part to hash and length). bool ContentNode::getContentNode(QSqlDatabase & database, ContentNode &node) { QSqlQuery query(database); query.prepare( "select id, title, authors, description, " "last_access, publisher, md5, " "rating, read_time, read_count, progress, attributes " "from content where name = :name and location = :location " "and size = :size" ); query.bindValue(":name", node.name()); query.bindValue(":location", node.location()); query.bindValue(":size", node.size()); if (query.exec() && query.next()) { int index = 0; node.id_ = query.value(index++).toInt(); node.title_ = query.value(index++).toString(); node.mutable_authors() = query.value(index++).toString(); node.mutable_description() = query.value(index++).toString(); node.mutable_last_access() = query.value(index++).toString(); node.mutable_publisher() = query.value(index++).toString(); node.mutable_md5() = query.value(index++).toString(); node.mutable_rating() = query.value(index++).toInt(); node.mutable_read_time() = query.value(index++).toInt(); node.mutable_read_count() = query.value(index++).toInt(); node.mutable_progress() = query.value(index++).toString(); node.mutable_attributes() = query.value(index++).toByteArray(); return true; } return false; }
bool ContentNode::getContentNodeByUrl(QSqlDatabase& database, const QString & url, ContentNode & node) { QSqlQuery query(database); query.prepare( "select id, name, location, title, authors, description, " "last_access, publisher, " "rating, read_time, read_count, progress, attributes " "from content where md5 = :md5" ); query.bindValue(":md5", url); if (query.exec() && query.next()) { int index = 0; node.id_ = query.value(index++).toInt(); node.name_ = query.value(index++).toString(); node.location_ = query.value(index++).toString(); node.title_ = query.value(index++).toString(); node.mutable_authors() = query.value(index++).toString(); node.mutable_description() = query.value(index++).toString(); node.mutable_last_access() = query.value(index++).toString(); node.mutable_publisher() = query.value(index++).toString(); node.mutable_md5() = url; node.mutable_rating() = query.value(index++).toInt(); node.mutable_read_time() = query.value(index++).toInt(); node.mutable_read_count() = query.value(index++).toInt(); node.mutable_progress() = query.value(index++).toString(); node.mutable_attributes() = query.value(index++).toByteArray(); return true; } return false; }
// Need to define the search policy. // - Match the name, location and size. // - Otherwise, we just ignore the request. // - We can also use the hash code to match the file. /// Query the content node in the specified database. /// \param database The sqlitepp wrapper of database. /// \param info The content node information returned by this function. /// \param absolute_path The absolute path of the node. /// \param create Create the content node automatically if not found. /// \return This function returns true if the content node is already in /// the database, otherwise it returns false. bool ContentNode::getContentNode(QSqlDatabase &database, ContentNode & node, const QString & absolute_path, bool create) { // Initialize query parameters and initialize all stuff // that does not rely on the database. QFileInfo info(absolute_path); node.mutable_size() = info.size(); node.mutable_location() = info.path(); node.mutable_name() = info.fileName(); // Query by name, location and size. QSqlQuery query(database); query.prepare( "select id, title, authors, description, " "last_access, publisher, md5, " "rating, read_time, read_count, progress, attributes " "from content where name = :name and location = :location " "and size = :size" ); query.bindValue(":name", node.name()); query.bindValue(":location", node.location()); query.bindValue(":size", node.size()); if (query.exec() && query.next()) { int index = 0; node.id_ = query.value(index++).toInt(); node.title_ = query.value(index++).toString(); node.mutable_authors() = query.value(index++).toString(); node.mutable_description() = query.value(index++).toString(); node.mutable_last_access() = query.value(index++).toString(); node.mutable_publisher() = query.value(index++).toString(); node.mutable_md5() = query.value(index++).toString(); node.mutable_rating() = query.value(index++).toInt(); node.mutable_read_time() = query.value(index++).toInt(); node.mutable_read_count() = query.value(index++).toInt(); node.mutable_progress() = query.value(index++).toString(); node.mutable_attributes() = query.value(index++).toByteArray(); return true; } // File has been moved, check the name and size. /* { statement st(database); st << "select id, title, authors, description, " << "last_access, publisher, md5, " << "rating, read_time, read_count " << "from content where name = :name and size = :size", node.id_), into(info.mutable_title()), into(info.mutable_authors()), into(info.mutable_description()), into(info.mutable_last_access()), into(info.mutable_publisher()), into(info.mutable_md5()), into(info.mutable_rating()), into(info.mutable_read_time()), into(info.mutable_read_count()), use(info.name()), use(info.size()); if (st.exec()) { return true; } } // File name has been changed, check the md5 only. // Check if the md5 is ready or not. Make sure md5 // is calculated only once. // TODO, maybe just ignore the node as it's not important. if (info.md5().empty() && FileMd5Sum(absolute_path, info.mutable_md5())) { statement st(database); st << "select id, title, authors, description, " << "last_access, publisher, " << "rating, read_time, read_count " << "from content where md5 = :md5", into(info.id_), into(info.mutable_title()), into(info.mutable_authors()), into(info.mutable_description()), into(info.mutable_last_access()), into(info.mutable_publisher()), into(info.mutable_rating()), into(info.mutable_read_time()), into(info.mutable_read_count()), use(info.md5()); if (st.exec()) { return true; } } */ // Insert into the database. Should change the function name. if (create) { createContentNode(database, node); } return false; }