15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/indexed_db/indexed_db_key.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebIDBKey;
13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing WebKit::WebIDBKeyType;
14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing WebKit::WebIDBKeyTypeArray;
15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing WebKit::WebIDBKeyTypeDate;
16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing WebKit::WebIDBKeyTypeInvalid;
17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing WebKit::WebIDBKeyTypeMin;
18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing WebKit::WebIDBKeyTypeNull;
19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing WebKit::WebIDBKeyTypeNumber;
20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing WebKit::WebIDBKeyTypeString;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Very rough estimate of minimum key size overhead.
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const size_t kOverheadSize = 16;
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static size_t CalculateArraySize(const IndexedDBKey::KeyArray& keys) {
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  size_t size(0);
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for (size_t i = 0; i < keys.size(); ++i)
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    size += keys[i].size_estimate();
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return size;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)template <typename T>
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static IndexedDBKey::KeyArray CopyKeyArray(const T& array) {
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  IndexedDBKey::KeyArray result;
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  result.reserve(array.size());
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (size_t i = 0; i < array.size(); ++i) {
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    result.push_back(IndexedDBKey(array[i]));
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return result;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IndexedDBKey::IndexedDBKey()
47ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    : type_(WebIDBKeyTypeNull),
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      date_(0),
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      number_(0),
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      size_estimate_(kOverheadSize) {}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochIndexedDBKey::IndexedDBKey(WebIDBKeyType type)
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : type_(type), date_(0), number_(0), size_estimate_(kOverheadSize) {
54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK(type == WebIDBKeyTypeNull || type == WebIDBKeyTypeInvalid);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochIndexedDBKey::IndexedDBKey(double number, WebIDBKeyType type)
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : type_(type),
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      date_(number),
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      number_(number),
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      size_estimate_(kOverheadSize + sizeof(number)) {
62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK(type == WebIDBKeyTypeNumber || type == WebIDBKeyTypeDate);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IndexedDBKey::IndexedDBKey(const KeyArray& keys)
66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    : type_(WebIDBKeyTypeArray),
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      array_(CopyKeyArray(keys)),
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      date_(0),
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      number_(0),
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      size_estimate_(kOverheadSize + CalculateArraySize(keys)) {}
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IndexedDBKey::IndexedDBKey(const string16& key)
73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    : type_(WebIDBKeyTypeString),
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      string_(key),
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      size_estimate_(kOverheadSize +
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     (key.length() * sizeof(string16::value_type))) {}
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IndexedDBKey::~IndexedDBKey() {}
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int IndexedDBKey::Compare(const IndexedDBKey& other) const {
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(IsValid());
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(other.IsValid());
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (type_ != other.type_)
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return type_ > other.type_ ? -1 : 1;
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  switch (type_) {
87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyTypeArray:
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      for (size_t i = 0; i < array_.size() && i < other.array_.size(); ++i) {
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (int result = array_[i].Compare(other.array_[i]))
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          return result;
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (array_.size() < other.array_.size())
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        return -1;
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (array_.size() > other.array_.size())
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        return 1;
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return 0;
97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyTypeString:
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return -other.string_.compare(string_);
99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyTypeDate:
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return (date_ < other.date_) ? -1 : (date_ > other.date_) ? 1 : 0;
101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyTypeNumber:
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return (number_ < other.number_) ? -1 : (number_ > other.number_) ? 1 : 0;
103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyTypeInvalid:
104ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyTypeNull:
105ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case WebIDBKeyTypeMin:
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      NOTREACHED();
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return 0;
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return 0;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool IndexedDBKey::IsLessThan(const IndexedDBKey& other) const {
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return Compare(other) < 0;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool IndexedDBKey::IsEqual(const IndexedDBKey& other) const {
11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return !Compare(other);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IndexedDBKey::IsValid() const {
122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (type_ == WebIDBKeyTypeInvalid || type_ == WebIDBKeyTypeNull)
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (type_ == WebIDBKeyTypeArray) {
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (size_t i = 0; i < array_.size(); i++) {
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!array_[i].IsValid())
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return false;
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return true;
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
136