/* * RESTHeart - the Web API for MongoDB * Copyright (C) SoftInstigate Srl * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.restheart.db; import com.mongodb.MongoClient; import com.mongodb.client.ListIndexesIterable; import static com.mongodb.client.model.Filters.eq; import com.mongodb.client.model.IndexOptions; import java.util.ArrayList; import org.restheart.utils.HttpStatus; import java.util.List; import java.util.concurrent.TimeUnit; import org.bson.BsonDocument; import org.bson.BsonInt32; import org.bson.BsonValue; import org.bson.Document; import org.bson.conversions.Bson; /** * * @author Andrea Di Cesare {@literal <andrea@softinstigate.com>} */ class IndexDAO { private final MongoClient client; public static final Bson METADATA_QUERY = eq("_id", "_properties"); private static final BsonDocument FIELDS_TO_RETURN_INDEXES; static { FIELDS_TO_RETURN_INDEXES = new BsonDocument(); FIELDS_TO_RETURN_INDEXES.put("key", new BsonInt32(1)); FIELDS_TO_RETURN_INDEXES.put("name", new BsonInt32(1)); } IndexDAO(MongoClient client) { this.client = client; } /** * * @param dbName * @param collName * @return */ List<BsonDocument> getCollectionIndexes(String dbName, String collName) { List<BsonDocument> ret = new ArrayList<>(); ListIndexesIterable<Document> indexes = client .getDatabase(dbName) .getCollection(collName, BsonDocument.class) .listIndexes(); indexes.iterator().forEachRemaining( i -> { BsonDocument bi = BsonDocument.parse(i.toJson()); BsonValue name = bi.remove("name"); bi.put("_id", name); ret.add(bi); }); return ret; } /** * * @param dbName * @param collection * @param keys * @param options */ void createIndex( String dbName, String collection, BsonDocument keys, BsonDocument options) { if (options == null) { client .getDatabase(dbName) .getCollection(collection) .createIndex(keys); } else { // need to find a way to get IndexOptions from json IndexOptions io = new IndexOptions(); io.background(true); client .getDatabase(dbName) .getCollection(collection) .createIndex(keys, getIndexOptions(options)); } } /** * * @param db * @param collection * @param indexId * @return */ int deleteIndex( String dbName, String collection, String indexId) { client .getDatabase(dbName) .getCollection(collection) .dropIndex(indexId); return HttpStatus.SC_NO_CONTENT; } IndexOptions getIndexOptions(BsonDocument options) { IndexOptions ret = new IndexOptions(); //***Options for All Index Types //name string if (options.containsKey("name") && options.get("name").isString()) { ret.name(options.get("name").asString().getValue()); } //background boolean if (options.containsKey("background") && options.get("background").isBoolean()) { ret.background(options.get("background").asBoolean().getValue()); } //expireAfterSeconds integer if (options.containsKey("expireAfterSeconds") && options.get("expireAfterSeconds").isInt32()) { ret.expireAfter(0l + options.get("expireAfterSeconds") .asInt32().getValue(), TimeUnit.SECONDS ); } //partialFilterExpression document if (options.containsKey("partialFilterExpression") && options.get("partialFilterExpression").isDocument()) { ret.partialFilterExpression(options.get("partialFilterExpression") .asDocument()); } //storageEngine document if (options.containsKey("storageEngine") && options.get("storageEngine").isDocument()) { ret.storageEngine(options.get("storageEngine") .asDocument()); } //unique boolean if (options.containsKey("unique") && options.get("unique").isBoolean()) { ret.unique(options.get("unique") .asBoolean().getValue()); } //sparse boolean if (options.containsKey("sparse") && options.get("sparse").isBoolean()) { ret.sparse(options.get("sparse") .asBoolean().getValue()); } //***Options for text Indexes //weights document if (options.containsKey("weights") && options.get("weights").isDocument()) { ret.weights(options.get("weights") .asDocument()); } //default_language string if (options.containsKey("default_language") && options.get("default_language").isString()) { ret.defaultLanguage(options.get("default_language") .asString().getValue()); } //language_override string if (options.containsKey("language_override") && options.get("language_override").isString()) { ret.languageOverride(options.get("language_override") .asString().getValue()); } //textIndexVersion integer if (options.containsKey("textIndexVersion") && options.get("textIndexVersion").isInt32()) { ret.textVersion(options.get("textIndexVersion") .asInt32().getValue()); } //***Options for 2dsphere Indexes //2dsphereIndexVersion integer if (options.containsKey("2dsphereIndexVersion") && options.get("2dsphereIndexVersion").isInt32()) { ret.sphereVersion(options.get("2dsphereIndexVersion") .asInt32().getValue()); } //***Options for 2d Indexes //bits integer if (options.containsKey("bits") && options.get("bits").isInt32()) { ret.bits(options.get("bits") .asInt32().getValue()); } //min number if (options.containsKey("min") && options.get("min").isDouble()) { ret.min(options.get("min") .asDouble().getValue()); } //max number if (options.containsKey("max") && options.get("max").isDouble()) { ret.max(options.get("max") .asDouble().getValue()); } //***Options for geoHaystack Indexes //bucketSize number if (options.containsKey("bucketSize") && options.get("bucketSize").isDouble()) { ret.bucketSize(options.get("bucketSize") .asDouble().getValue()); } return ret; } }