View Javadoc
1   /*
2    * #%L
3    * CreateIndexCommand.java - mongodb-async-driver - Allanbank Consulting, Inc.
4    * %%
5    * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package com.allanbank.mongodb.client.message;
21  
22  import com.allanbank.mongodb.ReadPreference;
23  import com.allanbank.mongodb.Version;
24  import com.allanbank.mongodb.bson.Document;
25  import com.allanbank.mongodb.bson.DocumentAssignable;
26  import com.allanbank.mongodb.bson.Element;
27  import com.allanbank.mongodb.bson.NumericElement;
28  import com.allanbank.mongodb.bson.builder.BuilderFactory;
29  import com.allanbank.mongodb.bson.builder.DocumentBuilder;
30  import com.allanbank.mongodb.client.VersionRange;
31  
32  /**
33   * Helper class to make generating a {@code createIndexes} command easier.
34   * 
35   * @see <a
36   *      href="http://docs.mongodb.org/manual/reference/command/createIndexes">createIndexes
37   *      reference manual.</a>
38   * @api.no This class is <b>NOT</b> part of the drivers API. This class may be
39   *         mutated in incompatible ways between any two releases of the driver.
40   * @copyright 2014, Allanbank Consulting, Inc., All Rights Reserved
41   */
42  public class CreateIndexCommand extends Command {
43      /**
44       * The first version of MongoDB to support the {@code createIndexes}
45       * command.
46       */
47      public static final Version REQUIRED_VERSION = Version.VERSION_2_6;
48  
49      /** The required server version range for the {@code createIndexes} command. */
50      public static final VersionRange REQUIRED_VERSION_RANGE = VersionRange
51              .minimum(REQUIRED_VERSION);
52  
53      /**
54       * Generates a name for the index based on the keys.
55       * 
56       * @param keys
57       *            The keys for the index.
58       * @return The name for the index.
59       */
60      public static String buildIndexName(final Element... keys) {
61          final StringBuilder nameBuilder = new StringBuilder();
62          for (final Element key : keys) {
63              if (nameBuilder.length() > 0) {
64                  nameBuilder.append('_');
65              }
66              nameBuilder.append(key.getName().replace(' ', '_'));
67              nameBuilder.append("_");
68              if (key instanceof NumericElement) {
69                  nameBuilder.append(((NumericElement) key).getIntValue());
70              }
71              else {
72                  nameBuilder.append(key.getValueAsString());
73              }
74          }
75          return nameBuilder.toString();
76      }
77  
78      /**
79       * Constructs the {@code createIndexes} command.
80       * 
81       * @param collectionName
82       *            The name of the collection the command is using. This should
83       *            be the real collection and not
84       *            {@link Command#COMMAND_COLLECTION $cmd}.
85       * @param keys
86       *            The index keys for the index.
87       * @param indexName
88       *            The name of the index.
89       * @param options
90       *            Options for the index. May be <code>null</code>.
91       * @return The {@code createIndexes} command.
92       */
93      private static Document buildCommand(final String collectionName,
94              final Element[] keys, final String indexName,
95              final DocumentAssignable options) {
96          final DocumentBuilder builder = BuilderFactory.start();
97  
98          builder.add("createIndexes", collectionName);
99  
100         final DocumentBuilder index = builder.pushArray("indexes").push();
101         final DocumentBuilder keysDoc = index.push("key");
102         for (final Element key : keys) {
103             keysDoc.add(key);
104         }
105 
106         index.add("name", indexName == null ? buildIndexName(keys) : indexName);
107 
108         if (options != null) {
109             for (final Element option : options.asDocument()) {
110                 index.add(option);
111             }
112         }
113 
114         return builder.build();
115     }
116 
117     /**
118      * Create a new CreateIndexCommand.
119      * 
120      * @param databaseName
121      *            The name of the database.
122      * @param collectionName
123      *            The name of the collection the command is using. This should
124      *            be the real collection and not
125      *            {@link Command#COMMAND_COLLECTION $cmd}.
126      * @param keys
127      *            The index keys for the index.
128      * @param indexName
129      *            The name of the index.
130      * @param options
131      *            Options for the index. May be <code>null</code>.
132      */
133     public CreateIndexCommand(final String databaseName,
134             final String collectionName, final Element[] keys,
135             final String indexName, final DocumentAssignable options) {
136         super(databaseName, collectionName, buildCommand(collectionName, keys,
137                 indexName, options), ReadPreference.PRIMARY,
138                 REQUIRED_VERSION_RANGE);
139     }
140 
141     /**
142      * Determines if the passed object is of this same type as this object and
143      * if so that its fields are equal.
144      * 
145      * @param object
146      *            The object to compare to.
147      * 
148      * @see java.lang.Object#equals(java.lang.Object)
149      */
150     @Override
151     public boolean equals(final Object object) {
152         boolean result = false;
153         if (this == object) {
154             result = true;
155         }
156         else if ((object != null) && (getClass() == object.getClass())) {
157             result = super.equals(object);
158         }
159         return result;
160     }
161 
162     /**
163      * Computes a reasonable hash code.
164      * 
165      * @return The hash code value.
166      */
167     @Override
168     public int hashCode() {
169         int result = 1;
170         result = (31 * result) + super.hashCode();
171         return result;
172     }
173 }