Home | History | Annotate | Download | only in sql
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <string>
      6 
      7 #include "base/bind.h"
      8 #include "base/file_util.h"
      9 #include "base/files/scoped_temp_dir.h"
     10 #include "sql/connection.h"
     11 #include "sql/statement.h"
     12 #include "sql/test/error_callback_support.h"
     13 #include "sql/test/scoped_error_ignorer.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 #include "third_party/sqlite/sqlite3.h"
     16 
     17 namespace {
     18 
     19 class SQLStatementTest : public testing::Test {
     20  public:
     21   virtual void SetUp() {
     22     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     23     ASSERT_TRUE(db_.Open(temp_dir_.path().AppendASCII("SQLStatementTest.db")));
     24   }
     25 
     26   virtual void TearDown() {
     27     db_.Close();
     28   }
     29 
     30   sql::Connection& db() { return db_; }
     31 
     32  private:
     33   base::ScopedTempDir temp_dir_;
     34   sql::Connection db_;
     35 };
     36 
     37 }  // namespace
     38 
     39 TEST_F(SQLStatementTest, Assign) {
     40   sql::Statement s;
     41   EXPECT_FALSE(s.is_valid());
     42 
     43   s.Assign(db().GetUniqueStatement("CREATE TABLE foo (a, b)"));
     44   EXPECT_TRUE(s.is_valid());
     45 }
     46 
     47 TEST_F(SQLStatementTest, Run) {
     48   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
     49   ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)"));
     50 
     51   sql::Statement s(db().GetUniqueStatement("SELECT b FROM foo WHERE a=?"));
     52   EXPECT_FALSE(s.Succeeded());
     53 
     54   // Stepping it won't work since we haven't bound the value.
     55   EXPECT_FALSE(s.Step());
     56 
     57   // Run should fail since this produces output, and we should use Step(). This
     58   // gets a bit wonky since sqlite says this is OK so succeeded is set.
     59   s.Reset(true);
     60   s.BindInt(0, 3);
     61   EXPECT_FALSE(s.Run());
     62   EXPECT_EQ(SQLITE_ROW, db().GetErrorCode());
     63   EXPECT_TRUE(s.Succeeded());
     64 
     65   // Resetting it should put it back to the previous state (not runnable).
     66   s.Reset(true);
     67   EXPECT_FALSE(s.Succeeded());
     68 
     69   // Binding and stepping should produce one row.
     70   s.BindInt(0, 3);
     71   EXPECT_TRUE(s.Step());
     72   EXPECT_TRUE(s.Succeeded());
     73   EXPECT_EQ(12, s.ColumnInt(0));
     74   EXPECT_FALSE(s.Step());
     75   EXPECT_TRUE(s.Succeeded());
     76 }
     77 
     78 // Error callback called for error running a statement.
     79 TEST_F(SQLStatementTest, ErrorCallback) {
     80   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a INTEGER PRIMARY KEY, b)"));
     81 
     82   int error = SQLITE_OK;
     83   sql::ScopedErrorCallback sec(
     84       &db(), base::Bind(&sql::CaptureErrorCallback, &error));
     85 
     86   // Insert in the foo table the primary key. It is an error to insert
     87   // something other than an number. This error causes the error callback
     88   // handler to be called with SQLITE_MISMATCH as error code.
     89   sql::Statement s(db().GetUniqueStatement("INSERT INTO foo (a) VALUES (?)"));
     90   EXPECT_TRUE(s.is_valid());
     91   s.BindCString(0, "bad bad");
     92   EXPECT_FALSE(s.Run());
     93   EXPECT_EQ(SQLITE_MISMATCH, error);
     94 }
     95 
     96 // Error ignorer works for error running a statement.
     97 TEST_F(SQLStatementTest, ScopedIgnoreError) {
     98   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a INTEGER PRIMARY KEY, b)"));
     99 
    100   sql::Statement s(db().GetUniqueStatement("INSERT INTO foo (a) VALUES (?)"));
    101   EXPECT_TRUE(s.is_valid());
    102 
    103   sql::ScopedErrorIgnorer ignore_errors;
    104   ignore_errors.IgnoreError(SQLITE_MISMATCH);
    105   s.BindCString(0, "bad bad");
    106   ASSERT_FALSE(s.Run());
    107   ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
    108 }
    109 
    110 TEST_F(SQLStatementTest, Reset) {
    111   ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
    112   ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)"));
    113   ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (4, 13)"));
    114 
    115   sql::Statement s(db().GetUniqueStatement(
    116       "SELECT b FROM foo WHERE a = ? "));
    117   s.BindInt(0, 3);
    118   ASSERT_TRUE(s.Step());
    119   EXPECT_EQ(12, s.ColumnInt(0));
    120   ASSERT_FALSE(s.Step());
    121 
    122   s.Reset(false);
    123   // Verify that we can get all rows again.
    124   ASSERT_TRUE(s.Step());
    125   EXPECT_EQ(12, s.ColumnInt(0));
    126   EXPECT_FALSE(s.Step());
    127 
    128   s.Reset(true);
    129   ASSERT_FALSE(s.Step());
    130 }
    131