// Copyright (c) 2012 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.

#include "storage/browser/database/databases_table.h"

#include <stdint.h>

#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "sql/statement.h"

namespace storage {

DatabaseDetails::DatabaseDetails() : estimated_size(0) { }

DatabaseDetails::DatabaseDetails(const DatabaseDetails& other) = default;

DatabaseDetails::~DatabaseDetails() {}

bool DatabasesTable::Init() {
  // 'Databases' schema:
  //   id              A unique ID assigned to each database
  //   origin          The originto which the database belongs. This is a
  //                   string that can be used as part of a file name
  //                   (http_webkit.org_0, for example).
  //   name            The database name.
  //   description     A short description of the database.
  //   estimated_size  The estimated size of the database.
  return db_->DoesTableExist("Databases") ||
      (db_->Execute(
           "CREATE TABLE Databases ("
           "id INTEGER PRIMARY KEY AUTOINCREMENT, "
           "origin TEXT NOT NULL, "
           "name TEXT NOT NULL, "
           "description TEXT NOT NULL, "
           "estimated_size INTEGER NOT NULL)") &&
       db_->Execute(
           "CREATE INDEX origin_index ON Databases (origin)") &&
       db_->Execute(
           "CREATE UNIQUE INDEX unique_index ON Databases (origin, name)"));
}

int64_t DatabasesTable::GetDatabaseID(const std::string& origin_identifier,
                                      const base::string16& database_name) {
  sql::Statement select_statement(db_->GetCachedStatement(
      SQL_FROM_HERE, "SELECT id FROM Databases WHERE origin = ? AND name = ?"));
  select_statement.BindString(0, origin_identifier);
  select_statement.BindString16(1, database_name);

  if (select_statement.Step()) {
    return select_statement.ColumnInt64(0);
  }

  return -1;
}

bool DatabasesTable::GetDatabaseDetails(const std::string& origin_identifier,
                                        const base::string16& database_name,
                                        DatabaseDetails* details) {
  DCHECK(details);
  sql::Statement select_statement(db_->GetCachedStatement(
      SQL_FROM_HERE, "SELECT description, estimated_size FROM Databases "
                     "WHERE origin = ? AND name = ?"));
  select_statement.BindString(0, origin_identifier);
  select_statement.BindString16(1, database_name);

  if (select_statement.Step()) {
    details->origin_identifier = origin_identifier;
    details->database_name = database_name;
    details->description = select_statement.ColumnString16(0);
    details->estimated_size = select_statement.ColumnInt64(1);
    return true;
  }

  return false;
}

bool DatabasesTable::InsertDatabaseDetails(const DatabaseDetails& details) {
  sql::Statement insert_statement(db_->GetCachedStatement(
      SQL_FROM_HERE, "INSERT INTO Databases (origin, name, description, "
                     "estimated_size) VALUES (?, ?, ?, ?)"));
  insert_statement.BindString(0, details.origin_identifier);
  insert_statement.BindString16(1, details.database_name);
  insert_statement.BindString16(2, details.description);
  insert_statement.BindInt64(3, details.estimated_size);

  return insert_statement.Run();
}

bool DatabasesTable::UpdateDatabaseDetails(const DatabaseDetails& details) {
  sql::Statement update_statement(db_->GetCachedStatement(
      SQL_FROM_HERE, "UPDATE Databases SET description = ?, "
                     "estimated_size = ? WHERE origin = ? AND name = ?"));
  update_statement.BindString16(0, details.description);
  update_statement.BindInt64(1, details.estimated_size);
  update_statement.BindString(2, details.origin_identifier);
  update_statement.BindString16(3, details.database_name);

  return (update_statement.Run() && db_->GetLastChangeCount());
}

bool DatabasesTable::DeleteDatabaseDetails(
    const std::string& origin_identifier,
    const base::string16& database_name) {
  sql::Statement delete_statement(db_->GetCachedStatement(
      SQL_FROM_HERE, "DELETE FROM Databases WHERE origin = ? AND name = ?"));
  delete_statement.BindString(0, origin_identifier);
  delete_statement.BindString16(1, database_name);

  return (delete_statement.Run() && db_->GetLastChangeCount());
}

bool DatabasesTable::GetAllOriginIdentifiers(
    std::vector<std::string>* origin_identifiers) {
  sql::Statement statement(db_->GetCachedStatement(
      SQL_FROM_HERE, "SELECT DISTINCT origin FROM Databases ORDER BY origin"));

  while (statement.Step())
    origin_identifiers->push_back(statement.ColumnString(0));

  return statement.Succeeded();
}

bool DatabasesTable::GetAllDatabaseDetailsForOriginIdentifier(
    const std::string& origin_identifier,
    std::vector<DatabaseDetails>* details_vector) {
  sql::Statement statement(db_->GetCachedStatement(
      SQL_FROM_HERE, "SELECT name, description, estimated_size "
                     "FROM Databases WHERE origin = ? ORDER BY name"));
  statement.BindString(0, origin_identifier);

  while (statement.Step()) {
    DatabaseDetails details;
    details.origin_identifier = origin_identifier;
    details.database_name = statement.ColumnString16(0);
    details.description = statement.ColumnString16(1);
    details.estimated_size = statement.ColumnInt64(2);
    details_vector->push_back(details);
  }

  return statement.Succeeded();
}

bool DatabasesTable::DeleteOriginIdentifier(
    const std::string& origin_identifier) {
  sql::Statement delete_statement(db_->GetCachedStatement(
      SQL_FROM_HERE, "DELETE FROM Databases WHERE origin = ?"));
  delete_statement.BindString(0, origin_identifier);

  return (delete_statement.Run() && db_->GetLastChangeCount());
}

}  // namespace storage
