Home | History | Annotate | Download | only in indexeddb
      1 /*
      2  * Copyright (C) 2011 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef IDBKey_h
     27 #define IDBKey_h
     28 
     29 #include "wtf/Forward.h"
     30 #include "wtf/RefCounted.h"
     31 #include "wtf/Vector.h"
     32 #include "wtf/text/WTFString.h"
     33 
     34 namespace WebCore {
     35 
     36 class IDBKey : public RefCounted<IDBKey> {
     37 public:
     38     typedef Vector<RefPtr<IDBKey> > KeyArray;
     39 
     40     static PassRefPtr<IDBKey> createInvalid()
     41     {
     42         return adoptRef(new IDBKey());
     43     }
     44 
     45     static PassRefPtr<IDBKey> createNumber(double number)
     46     {
     47         return adoptRef(new IDBKey(NumberType, number));
     48     }
     49 
     50     static PassRefPtr<IDBKey> createString(const String& string)
     51     {
     52         return adoptRef(new IDBKey(string));
     53     }
     54 
     55     static PassRefPtr<IDBKey> createDate(double date)
     56     {
     57         return adoptRef(new IDBKey(DateType, date));
     58     }
     59 
     60     static PassRefPtr<IDBKey> createMultiEntryArray(const KeyArray& array)
     61     {
     62         KeyArray result;
     63 
     64         size_t sizeEstimate = 0;
     65         for (size_t i = 0; i < array.size(); i++) {
     66             if (!array[i]->isValid())
     67                 continue;
     68 
     69             bool skip = false;
     70             for (size_t j = 0; j < result.size(); j++) {
     71                 if (array[i]->isEqual(result[j].get())) {
     72                     skip = true;
     73                     break;
     74                 }
     75             }
     76             if (!skip) {
     77                 result.append(array[i]);
     78                 sizeEstimate += array[i]->m_sizeEstimate;
     79             }
     80         }
     81         RefPtr<IDBKey> idbKey = adoptRef(new IDBKey(result, sizeEstimate));
     82         ASSERT(idbKey->isValid());
     83         return idbKey.release();
     84     }
     85 
     86     static PassRefPtr<IDBKey> createArray(const KeyArray& array)
     87     {
     88         size_t sizeEstimate = 0;
     89         for (size_t i = 0; i < array.size(); ++i)
     90             sizeEstimate += array[i]->m_sizeEstimate;
     91 
     92         return adoptRef(new IDBKey(array, sizeEstimate));
     93     }
     94 
     95     ~IDBKey();
     96 
     97     // In order of the least to the highest precedent in terms of sort order.
     98     enum Type {
     99         InvalidType = 0,
    100         ArrayType,
    101         StringType,
    102         DateType,
    103         NumberType,
    104         MinType
    105     };
    106 
    107     Type type() const { return m_type; }
    108     bool isValid() const;
    109 
    110     const KeyArray& array() const
    111     {
    112         ASSERT(m_type == ArrayType);
    113         return m_array;
    114     }
    115 
    116     const String& string() const
    117     {
    118         ASSERT(m_type == StringType);
    119         return m_string;
    120     }
    121 
    122     double date() const
    123     {
    124         ASSERT(m_type == DateType);
    125         return m_number;
    126     }
    127 
    128     double number() const
    129     {
    130         ASSERT(m_type == NumberType);
    131         return m_number;
    132     }
    133 
    134     int compare(const IDBKey* other) const;
    135     bool isLessThan(const IDBKey* other) const;
    136     bool isEqual(const IDBKey* other) const;
    137 
    138     size_t sizeEstimate() const { return m_sizeEstimate; }
    139 
    140     static int compareTypes(Type a, Type b)
    141     {
    142         return b - a;
    143     }
    144 
    145     using RefCounted<IDBKey>::ref;
    146     using RefCounted<IDBKey>::deref;
    147 
    148 private:
    149     IDBKey() : m_type(InvalidType), m_number(0), m_sizeEstimate(OverheadSize) { }
    150     IDBKey(Type type, double number) : m_type(type), m_number(number), m_sizeEstimate(OverheadSize + sizeof(double)) { }
    151     explicit IDBKey(const String& value) : m_type(StringType), m_string(value), m_number(0), m_sizeEstimate(OverheadSize + value.length() * sizeof(UChar)) { }
    152     IDBKey(const KeyArray& keyArray, size_t arraySize) : m_type(ArrayType), m_array(keyArray), m_number(0), m_sizeEstimate(OverheadSize + arraySize) { }
    153 
    154     const Type m_type;
    155     const KeyArray m_array;
    156     const String m_string;
    157     const double m_number;
    158 
    159     const size_t m_sizeEstimate;
    160 
    161     // Very rough estimate of minimum key size overhead.
    162     enum { OverheadSize = 16 };
    163 };
    164 
    165 } // namespace WebCore
    166 
    167 #endif // IDBKey_h
    168