| // Copyright (c) 2006-2008 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_COMMON_SQLITE_COMPILED_STATEMENT_H_ |
| #define CHROME_COMMON_SQLITE_COMPILED_STATEMENT_H_ |
| #pragma once |
| |
| #include <map> |
| #include <string> |
| |
| #include "base/basictypes.h" |
| |
| struct sqlite3; |
| class SQLStatement; |
| |
| // Stores a list of precompiled sql statements for a database. Each statement |
| // is given a unique name by the caller. |
| // |
| // Note: see comments on descructor. |
| class SqliteStatementCache { |
| public: |
| // You must call set_db before anything else if you use this constructor. |
| SqliteStatementCache() : db_(NULL) { |
| } |
| |
| explicit SqliteStatementCache(sqlite3* db) : db_(db) { |
| } |
| |
| // This object must be deleted before the sqlite connection it is associated |
| // with. Otherwise, sqlite seems to keep the file open because there are open |
| // statements. |
| ~SqliteStatementCache(); |
| |
| void set_db(sqlite3* db); |
| |
| // Creates or retrieves a cached SQL statement identified by the given |
| // (name, number) pair. |
| // |
| // The name and number can be anything the caller wants, but must uniquely |
| // identify the SQL. The caller must ensure that every call with the same |
| // number and name has the same SQL. |
| // |
| // In practice the number and name is supposed to be a file and line number. |
| // (See the SQLITE_UNIQUE_STATEMENT macro below.) Recommended practice is to |
| // use 0 for the function number if you are not using this scheme, and just |
| // use a name you like. |
| // |
| // On error, NULL is returned. Otherwise, the statement for the given SQL is |
| // returned. This pointer is cached and owned by this class. |
| // |
| // The caller should not cache this value since it may be used by others. |
| // The caller should reset the statement when it is complete so that |
| // subsequent callers do not get bound stuff. |
| SQLStatement* GetStatement(const char* func_name, |
| int func_number, |
| const char* sql) { |
| return InternalGetStatement(func_name, func_number, sql); |
| } |
| |
| // Returns the cached statement if it has already been created, or NULL if it |
| // has not. |
| SQLStatement* GetExistingStatement(const char* func_name, |
| int func_number) { |
| return InternalGetStatement(func_name, func_number, NULL); |
| } |
| |
| private: |
| // The key used for precompiled function lookup. |
| struct FuncID { |
| int number; |
| std::string name; |
| |
| // Used as a key in the map below, so we need this comparator. |
| bool operator<(const FuncID& other) const; |
| }; |
| |
| // Backend for GetStatement and GetExistingStatement. If sql is NULL, we will |
| // only look for an existing statement and return NULL if there is not a |
| // matching one. If it is non-NULL, we will create it if it doesn't exist. |
| SQLStatement* InternalGetStatement(const char* func_name, |
| int func_number, |
| const char* sql); |
| |
| sqlite3* db_; |
| |
| // This object owns the statement pointers, which it must manually free. |
| typedef std::map<FuncID, SQLStatement*> StatementMap; |
| StatementMap statements_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SqliteStatementCache); |
| }; |
| |
| // Automatically creates or retrieves a statement from the given cache, and |
| // automatically resets the statement when it goes out of scope. |
| class SqliteCompiledStatement { |
| public: |
| // See SqliteStatementCache::GetStatement for a description of these args. |
| SqliteCompiledStatement(const char* func_name, |
| int func_number, |
| SqliteStatementCache& cache, |
| const char* sql); |
| ~SqliteCompiledStatement(); |
| |
| // Call to see if this statement is valid or not. Using this statement will |
| // segfault if it is not valid. |
| bool is_valid() const { return !!statement_; } |
| |
| // Allow accessing this object to be like accessing a statement for |
| // convenience. The caller must ensure the statement is_valid() before using |
| // these two functions. |
| SQLStatement& operator*(); |
| SQLStatement* operator->(); |
| SQLStatement* statement(); |
| |
| private: |
| // The sql statement if valid, NULL if not valid. This pointer is NOT owned |
| // by this class, it is owned by the statement cache object. |
| SQLStatement* statement_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SqliteCompiledStatement); |
| }; |
| |
| // Creates a compiled statement that has a unique name based on the file and |
| // line number. Example: |
| // |
| // SQLITE_UNIQUE_STATEMENT(var_name, cache, "SELECT * FROM foo"); |
| // if (!var_name.is_valid()) |
| // return oops; |
| // var_name->bind_XXX( |
| // var_name->step(); |
| // ... |
| #define SQLITE_UNIQUE_STATEMENT(var_name, cache, sql) \ |
| SqliteCompiledStatement var_name(__FILE__, __LINE__, cache, sql) |
| |
| #endif // CHROME_COMMON_SQLITE_COMPILED_STATEMENT_H_ |