summaryrefslogtreecommitdiffstats
path: root/chrome/common/sqlite_compiled_statement.h
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/common/sqlite_compiled_statement.h
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common/sqlite_compiled_statement.h')
-rw-r--r--chrome/common/sqlite_compiled_statement.h171
1 files changed, 171 insertions, 0 deletions
diff --git a/chrome/common/sqlite_compiled_statement.h b/chrome/common/sqlite_compiled_statement.h
new file mode 100644
index 0000000..ad12b45
--- /dev/null
+++ b/chrome/common/sqlite_compiled_statement.h
@@ -0,0 +1,171 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CHROME_COMMON_SQLITE_COMPILED_STATEMENT__
+#define CHROME_COMMON_SQLITE_COMPILED_STATEMENT__
+
+#include <map>
+#include <string>
+
+#include "base/logging.h"
+#include "chrome/common/sqlite_utils.h"
+#include "chrome/third_party/sqlite/sqlite3.h"
+
+// 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) {
+ }
+
+ 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) {
+ DCHECK(!db_) << "Setting the database twice";
+ db_ = 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_EVIL_CONSTRUCTORS(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*() {
+ DCHECK(statement_) << "Should check is_valid() before using the statement.";
+ return *statement_;
+ }
+ SQLStatement* operator->() {
+ DCHECK(statement_) << "Should check is_valid() before using the statement.";
+ return statement_;
+ }
+ SQLStatement* statement() {
+ DCHECK(statement_) << "Should check is_valid() before using the statement.";
+ return 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_EVIL_CONSTRUCTORS(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__