com.themodernway.server.mongodb.MongoDB Maven / Gradle / Ivy
/*
* Copyright (c) 2018, The Modern Way. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.themodernway.server.mongodb;
import static com.mongodb.client.model.Filters.and;
import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Filters.exists;
import static com.mongodb.client.model.Filters.gt;
import static com.mongodb.client.model.Filters.gte;
import static com.mongodb.client.model.Filters.in;
import static com.mongodb.client.model.Filters.lt;
import static com.mongodb.client.model.Filters.lte;
import static com.mongodb.client.model.Filters.ne;
import static com.mongodb.client.model.Filters.nin;
import static com.mongodb.client.model.Filters.nor;
import static com.mongodb.client.model.Filters.not;
import static com.mongodb.client.model.Filters.or;
import static com.mongodb.client.model.Filters.regex;
import static com.themodernway.server.mongodb.IMongoConstants.DOCUMENT;
import static com.themodernway.server.mongodb.IMongoConstants.ENSUREID;
import static com.themodernway.server.mongodb.IMongoConstants.INCLUDE_N;
import static com.themodernway.server.mongodb.IMongoConstants.INCLUDE_Y;
import static com.themodernway.server.mongodb.IMongoConstants.MONGODB_ID_KEY;
import static com.themodernway.server.mongodb.IMongoConstants.ORDER_A;
import static com.themodernway.server.mongodb.IMongoConstants.ORDER_D;
import static com.themodernway.server.mongodb.IMongoConstants.UPSERT_OPTIONS_TRUE;
import java.io.Closeable;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import org.bson.BSON;
import org.bson.BsonDocument;
import org.bson.BsonInt32;
import org.bson.BsonValue;
import org.bson.Document;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.conversions.Bson;
import org.slf4j.Logger;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ReadPreference;
import com.mongodb.ServerAddress;
import com.mongodb.WriteConcern;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.FindIterable;
import com.mongodb.client.ListIndexesIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;
import com.mongodb.client.model.IndexOptions;
import com.themodernway.common.api.java.util.CommonOps;
import com.themodernway.common.api.java.util.StringOps;
import com.themodernway.common.api.types.INamed;
import com.themodernway.server.core.ICoreCommon;
import com.themodernway.server.core.json.JSONUtils;
import com.themodernway.server.core.logging.IHasLogging;
import com.themodernway.server.core.logging.LoggingOps;
import com.themodernway.server.mongodb.support.spring.IMongoDBCollectionOptions;
import com.themodernway.server.mongodb.support.spring.IMongoDBOptions;
public final class MongoDB implements ICoreCommon
{
private static final Logger m_logger = LoggingOps.getLogger(MongoDB.class);
private final MongoClient m_mongo;
private final String m_usedb;
private final boolean m_useid;
private final Map m_dbops;
@SuppressWarnings("deprecation")
public MongoDB(final List addr, final List auth, final MongoClientOptions opts, final boolean repl, final String usedb, final boolean useid, final Map dbops)
{
m_useid = useid;
m_dbops = requireNonNull(dbops);
m_usedb = requireTrimOrNull(usedb);
BSON.addEncodingHook(BigDecimal.class, object -> {
if (null == object)
{
return null;
}
return JSONUtils.asDouble(object);
});
BSON.addEncodingHook(BigInteger.class, object -> {
if (null == object)
{
return null;
}
final Long lval = JSONUtils.asLong(object);
if (null != lval)
{
return lval;
}
return JSONUtils.asInteger(object);
});
if (addr.isEmpty())
{
throw new IllegalArgumentException("no ServerAddress");
}
if ((addr.size() == 1) && (false == repl))
{
final ServerAddress main = addr.get(0);
if (null == main)
{
throw new IllegalArgumentException("null ServerAddress");
}
if ((null == auth) || (auth.isEmpty()))
{
m_mongo = new MongoClient(main, requireNonNull(opts));
}
else
{
m_mongo = new MongoClient(main, auth, requireNonNull(opts));
}
}
else
{
if ((null == auth) || (auth.isEmpty()))
{
m_mongo = new MongoClient(addr, requireNonNull(opts));
}
else
{
m_mongo = new MongoClient(addr, auth, requireNonNull(opts));
}
}
}
@Override
public Logger logger()
{
return m_logger;
}
public boolean isAddingID()
{
return m_useid;
}
public void close()
{
if (null != m_mongo)
{
m_mongo.close();
}
}
public List getDatabaseNames()
{
return toUnmodifiableList(toUnique(m_mongo.listDatabaseNames().into(arrayList())));
}
public final MDatabase db()
{
return db(m_usedb);
}
public final MDatabase db(final String name)
{
return db(name, isAddingID());
}
public final MDatabase db(String name, boolean id)
{
name = requireTrimOrNull(name);
final IMongoDBOptions op = m_dbops.get(name);
if (null != op)
{
id = op.isCreateID();
}
return new MDatabase(m_mongo.getDatabase(name), id, op);
}
public static final class MDatabase implements ICoreCommon, INamed
{
private final MongoDatabase m_db;
private final IMongoDBOptions m_op;
private final boolean m_id;
private static final Logger m_logger = LoggingOps.getLogger(MDatabase.class);
protected MDatabase(final MongoDatabase db, final boolean id, final IMongoDBOptions op)
{
m_id = id;
m_op = op;
m_db = requireNonNull(db);
}
@Override
public Logger logger()
{
return m_logger;
}
public boolean isCreateID()
{
return m_id;
}
@Override
public final String getName()
{
return m_db.getName();
}
public final void drop()
{
m_db.drop();
}
public final boolean isCollection(final String name)
{
return getCollectionNames().contains(requireTrimOrNull(name));
}
public final List getCollectionNames()
{
return toUnmodifiableList(toUnique(m_db.listCollectionNames().into(arrayList())));
}
public final MCollection collection(String name)
{
name = requireTrimOrNull(name);
if (null != m_op)
{
final IMongoDBCollectionOptions cops = m_op.getCollectionOptions(name);
if (null != cops)
{
return new MCollection(m_db.getCollection(name), cops.isCreateID());
}
}
return new MCollection(m_db.getCollection(name), isCreateID());
}
public final MCollection collection(String name, final MCollectionPreferences opts)
{
name = requireTrimOrNull(name);
boolean crid = isCreateID();
if (null != m_op)
{
final IMongoDBCollectionOptions cops = m_op.getCollectionOptions(name);
if (null != cops)
{
crid = cops.isCreateID();
}
if ((null != opts) && (opts.isValid()))
{
return opts.withCollectionOptions(m_db.getCollection(name), crid);
}
}
return new MCollection(m_db.getCollection(name), crid);
}
}
public static final class MCollectionPreferences implements IHasLogging
{
private final WriteConcern m_write;
private final ReadPreference m_prefs;
private final CodecRegistry m_codec;
private static final Logger m_logger = LoggingOps.getLogger(MCollectionPreferences.class);
public MCollectionPreferences(final WriteConcern write, final ReadPreference prefs, final CodecRegistry codec)
{
m_write = write;
m_prefs = prefs;
m_codec = codec;
}
public MCollectionPreferences(final WriteConcern write)
{
this(write, null, null);
}
public MCollectionPreferences(final ReadPreference prefs)
{
this(null, prefs, null);
}
public MCollectionPreferences(final CodecRegistry codec)
{
this(null, null, codec);
}
public MCollectionPreferences(final WriteConcern write, final ReadPreference prefs)
{
this(write, prefs, null);
}
public MCollectionPreferences(final WriteConcern write, final CodecRegistry codec)
{
this(write, null, codec);
}
public MCollectionPreferences(final ReadPreference prefs, final CodecRegistry codec)
{
this(null, prefs, codec);
}
final boolean isValid()
{
return (false == ((null == m_write) && (null == m_prefs) && (null == m_codec)));
}
final MCollection withCollectionOptions(final MongoCollection collection, final boolean id)
{
return new MCollection(withCodecRegistry(withReadPreference(withWriteConcern(collection, m_write), m_prefs), m_codec), id);
}
private static final MongoCollection withWriteConcern(final MongoCollection collection, final WriteConcern write)
{
if (null == write)
{
return collection;
}
return collection.withWriteConcern(write);
}
private static final MongoCollection withReadPreference(final MongoCollection collection, final ReadPreference prefs)
{
if (null == prefs)
{
return collection;
}
return collection.withReadPreference(prefs);
}
private static final MongoCollection withCodecRegistry(final MongoCollection collection, final CodecRegistry codec)
{
if (null == codec)
{
return collection;
}
return collection.withCodecRegistry(codec);
}
@Override
public Logger logger()
{
return m_logger;
}
}
public static final class MCollection implements ICoreCommon, INamed
{
private final MongoCollection m_collection;
private final boolean m_id;
private static final Logger m_logger = LoggingOps.getLogger(MCollection.class);
protected MCollection(final MongoCollection collection, final boolean id)
{
m_collection = requireNonNull(collection);
m_id = id;
}
@Override
public Logger logger()
{
return m_logger;
}
public boolean isCreateID()
{
return m_id;
}
@Override
public final String getName()
{
return m_collection.getNamespace().getCollectionName();
}
public final String createIndex(final Map keys)
{
return m_collection.createIndex(DOCUMENT(keys));
}
public final String createIndex(final Map keys, final String name)
{
return m_collection.createIndex(DOCUMENT(keys), new IndexOptions().name(requireNonNull(name)));
}
public final String createIndex(final Map keys, final IndexOptions opts)
{
return m_collection.createIndex(DOCUMENT(keys), requireNonNull(opts));
}
public final MCollection dropIndex(final String name)
{
m_collection.dropIndex(requireNonNull(name));
return this;
}
public final MCollection dropIndexes()
{
m_collection.dropIndexes();
return this;
}
public final MIndexCursor getIndexes()
{
return new MIndexCursor(m_collection.listIndexes());
}
@SafeVarargs
public final MAggregateCursor aggregate(final T... list)
{
return aggregate(new MAggregationPipeline(requireNonNull(list)));
}
public final MAggregateCursor aggregate(final List list)
{
return aggregate(new MAggregationPipeline(requireNonNull(list)));
}
public final MAggregateCursor aggregate(final MAggregationPipeline pipeline)
{
return new MAggregateCursor(m_collection.aggregate(requireNonNull(pipeline.pipeline())));
}
public final void drop()
{
m_collection.drop();
}
public final long deleteMany(final Map query)
{
return deleteMany(new MQuery(query));
}
public final long deleteMany(final MQuery query)
{
return m_collection.deleteMany(requireNonNull(query)).getDeletedCount();
}
public final boolean deleteOne(final Map query)
{
return deleteOne(new MQuery(query));
}
public final boolean deleteOne(final MQuery query)
{
return (m_collection.deleteOne(requireNonNull(query)).getDeletedCount() == 1L);
}
public final Map insertOne(final Map record)
{
if (isCreateID())
{
final Map withid = ENSUREID(requireNonNull(record));
m_collection.insertOne(DOCUMENT(withid));
return withid;
}
else
{
m_collection.insertOne(DOCUMENT(record));
return record;
}
}
public final MCollection insertMany(final List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy