// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_HISTORY_TEXT_DATABASE_H_ #define CHROME_BROWSER_HISTORY_TEXT_DATABASE_H_ #pragma once #include <set> #include <vector> #include "app/sql/connection.h" #include "app/sql/meta_table.h" #include "base/basictypes.h" #include "base/file_path.h" #include "base/string16.h" #include "chrome/browser/history/history_types.h" #include "googleurl/src/gurl.h" namespace history { // Encapsulation of a full-text indexed database file. class TextDatabase { public: typedef int DBIdent; typedef std::set<GURL> URLSet; // Returned from the search function. struct Match { Match(); ~Match(); // URL of the match. GURL url; // The title is returned because the title in the text database and the URL // database may differ. This happens because we capture the title when the // body is captured, and don't update it later. string16 title; // Time the page that was returned was visited. base::Time time; // Identifies any found matches in the title of the document. These are not // included in the snippet. Snippet::MatchPositions title_match_positions; // Snippet of the match we generated from the body. Snippet snippet; }; // Note: You must call init which must succeed before using this class. // // Computes the matches for the query, returning results in decreasing order // of visit time. // // This function will attach the new database to the given database // connection. This allows one sqlite3 object to share many TextDatabases, // meaning that they will all share the same cache, which allows us to limit // the total size that text indexing databasii can take up. // // |file_name| is the name of the file on disk. // // ID is the identifier for the database. It should uniquely identify it among // other databases on disk and in the sqlite connection. // // |allow_create| indicates if we want to allow creation of the file if it // doesn't exist. For files associated with older time periods, we don't want // to create them if they don't exist, so this flag would be false. TextDatabase(const FilePath& path, DBIdent id, bool allow_create); ~TextDatabase(); // Initializes the database connection and creates the file if the class // was created with |allow_create|. If the file couldn't be opened or // created, this will return false. No other functions should be called // after this. bool Init(); // Allows updates to be batched. This gives higher performance when multiple // updates are happening because every insert doesn't require a sync to disk. // Transactions can be nested, only the outermost one will actually count. void BeginTransaction(); void CommitTransaction(); // For testing, returns the file name of the database so it can be deleted // after the test. This is valid even before Init() is called. const FilePath& file_name() const { return file_name_; } // Returns a NULL-terminated string that is the base of history index files, // which is the part before the database identifier. For example // "History Index *". This is for finding existing database files. static const FilePath::CharType* file_base(); // Converts a filename on disk (optionally including a path) to a database // identifier. If the filename doesn't have the correct format, returns 0. static DBIdent FileNameToID(const FilePath& file_path); // Changing operations ------------------------------------------------------- // Adds the given data to the page. Returns true on success. The data should // already be converted to UTF-8. bool AddPageData(base::Time time, const std::string& url, const std::string& title, const std::string& contents); // Deletes the indexed data exactly matching the given URL/time pair. void DeletePageData(base::Time time, const std::string& url); // Optimizes the tree inside the database. This will, in addition to making // access faster, remove any deleted data from the database (normally it is // added again as "removed" and it is manually cleaned up when it decides to // optimize it naturally). It is bad for privacy if a user is deleting a // page from history but it still exists in the full text database in some // form. This function will clean that up. void Optimize(); // Querying ------------------------------------------------------------------ // Executes the given query. See QueryOptions for more info on input. // // The results are appended to any existing ones in |*results|, and the first // time considered for the output is in |first_time_searched| // (see QueryResults for more). // // Any URLs found will be added to |unique_urls|. If a URL is already in the // set, additional results will not be added (giving the ability to uniquify // URL results). // // Callers must run QueryParser on the user text and pass the results of the // QueryParser to this method as the query string. void GetTextMatches(const std::string& query, const QueryOptions& options, std::vector<Match>* results, URLSet* unique_urls, base::Time* first_time_searched); // Converts the given database identifier to a filename. This does not include // the path, just the file and extension. static FilePath IDToFileName(DBIdent id); private: // Ensures that the tables and indices are created. Returns true on success. bool CreateTables(); // The sql database. Not valid until Init is called. sql::Connection db_; const FilePath path_; const DBIdent ident_; const bool allow_create_; // Full file name of the file on disk, computed in Init(). FilePath file_name_; sql::MetaTable meta_table_; DISALLOW_COPY_AND_ASSIGN(TextDatabase); }; } // namespace history #endif // CHROME_BROWSER_HISTORY_TEXT_DATABASE_H_