package org.javers.repository.mongo; import com.mongodb.BasicDBObject; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.bson.Document; import org.javers.repository.mongo.model.MongoHeadId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; /** * @author bartosz.walacik */ class MongoSchemaManager { static final int ASC = 1; static final String SNAPSHOTS = "jv_snapshots"; static final String COMMIT_ID = "commitMetadata.id"; static final String COMMIT_DATE = "commitMetadata.commitDate"; static final String COMMIT_AUTHOR = "commitMetadata.author"; static final String COMMIT_PROPERTIES = "commitMetadata.properties"; static final String GLOBAL_ID_KEY = "globalId_key"; static final String GLOBAL_ID_ENTITY = "globalId.entity"; static final String GLOBAL_ID_OWNER_ID_ENTITY = "globalId.ownerId.entity"; static final String GLOBAL_ID_FRAGMENT = "globalId.fragment"; static final String GLOBAL_ID_VALUE_OBJECT = "globalId.valueObject"; static final String SNAPSHOT_VERSION = "version"; static final String CHANGED_PROPERTIES = "changedProperties"; static final String OBJECT_ID = "_id"; private static final Logger logger = LoggerFactory.getLogger(MongoSchemaManager.class); private final MongoDatabase mongo; MongoSchemaManager(MongoDatabase mongo) { this.mongo = mongo; } public void ensureSchema() { //ensures collections and indexes MongoCollection<Document> snapshots = snapshotsCollection(); snapshots.createIndex(new BasicDBObject(GLOBAL_ID_KEY, ASC)); snapshots.createIndex(new BasicDBObject(GLOBAL_ID_VALUE_OBJECT, ASC)); snapshots.createIndex(new BasicDBObject(GLOBAL_ID_OWNER_ID_ENTITY, ASC)); snapshots.createIndex(new BasicDBObject(CHANGED_PROPERTIES, ASC)); snapshots.createIndex(new BasicDBObject(COMMIT_PROPERTIES + ".key", ASC).append(COMMIT_PROPERTIES + ".value", ASC)); headCollection(); //schema migration script from JaVers 2.0 to 2.1 dropIndexIfExists(snapshots, GLOBAL_ID_ENTITY); //schema migration script from JaVers 1.1 to 1.2 Document doc = snapshots.find().first(); if (doc != null) { Object stringCommitId = ((Map)doc.get("commitMetadata")).get("id"); if (stringCommitId instanceof String) { logger.info("executing db migration script, from JaVers 1.1 to 1.2 ..."); Document update = new Document("eval", "function() { \n"+ " db.jv_snapshots.find().forEach( \n"+ " function(snapshot) { \n"+ " snapshot.commitMetadata.id = Number(snapshot.commitMetadata.id); \n"+ " db.jv_snapshots.save(snapshot); } \n" + " ); "+ " return 'ok'; \n"+ "}" ); Document ret = mongo.runCommand(update); logger.info("result: \n "+ ret.toJson()); } } } MongoCollection<Document> snapshotsCollection() { return mongo.getCollection(SNAPSHOTS); } MongoCollection<Document> headCollection() { return mongo.getCollection(MongoHeadId.COLLECTION_NAME); } private static void dropIndexIfExists(MongoCollection<Document> col, String fieldName){ for (Document d : col.listIndexes()) { if (d.get("key", Document.class).containsKey(fieldName)) { logger.warn("Schema migration. Dropping index: "+fieldName +" ..."); try { col.dropIndex(fieldName); }catch (Exception swallowed){} //because not implemented in Fongo return; } } } }