Skip to content

Commit

Permalink
fixed custom ids lost on create(), fixed nested object structure flat…
Browse files Browse the repository at this point in the history
…tened to string and field values converted to string
  • Loading branch information
albogdano committed May 8, 2016
1 parent 19d3c72 commit 577cdae
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 19 deletions.
49 changes: 31 additions & 18 deletions src/main/java/com/erudika/para/persistence/MongoDBDAO.java
Expand Up @@ -26,7 +26,6 @@
import javax.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.erudika.para.annotations.Locked;
Expand Down Expand Up @@ -59,6 +58,7 @@ public class MongoDBDAO implements DAO {

private static final Logger logger = LoggerFactory.getLogger(MongoDBDAO.class);
private static final String _ID = "_id";
private static final String _OBJECT_ID = "_ObjectId";

public MongoDBDAO() { }

Expand All @@ -71,17 +71,15 @@ public <P extends ParaObject> String create(String appid, P so) {
if (so == null) {
return null;
}
if (!StringUtils.contains(so.getId(), Config.SEPARATOR)) {
if (StringUtils.isBlank(so.getId()) || !ObjectId.isValid(so.getId())) {
so.setId(MongoDBUtils.generateNewId());
logger.debug("Generated id: " + so.getId());
}
if (StringUtils.isBlank(so.getId())) {
so.setId(MongoDBUtils.generateNewId());
logger.debug("Generated id: " + so.getId());
}
if (so.getTimestamp() == null) {
so.setTimestamp(Utils.timestamp());
}
so.setAppid(appid);
createRow(so.getId(), appid, toRow(so, null));
createRow(so.getId(), appid, toRow(so, null, false, true));
logger.debug("DAO.create() {}", so.getId());
return so.getId();
}
Expand Down Expand Up @@ -182,15 +180,15 @@ public <P extends ParaObject> void createAll(String appid, List<P> objects) {
List<Document> documents = new ArrayList<Document>();
for (ParaObject so : objects) {
if (so != null) {
if (StringUtils.isBlank(so.getId()) || !ObjectId.isValid(so.getId())) {
if (StringUtils.isBlank(so.getId())) {
so.setId(MongoDBUtils.generateNewId());
logger.debug("Generated id: " + so.getId());
}
if (so.getTimestamp() == null) {
so.setTimestamp(Utils.timestamp());
}
so.setAppid(appid);
documents.add(toRow(so, null));
documents.add(toRow(so, null, false, true));
}
}
if (!documents.isEmpty()) {
Expand Down Expand Up @@ -231,20 +229,21 @@ public <P extends ParaObject> List<P> readPage(String appid, Pager pager) {
try {
String lastKey = pager.getLastKey();
MongoCursor<Document> cursor;
Bson filter = Filters.gt(_ID, lastKey);
Bson filter = Filters.gt(_OBJECT_ID, lastKey);
if (lastKey == null) {
cursor = getTable(appid).find().batchSize(pager.getLimit()).limit(pager.getLimit()).iterator();
} else {
cursor = getTable(appid).find(filter).batchSize(pager.getLimit()).limit(pager.getLimit()).iterator();
}
while (cursor.hasNext()) {
P obj = fromRow(cursor.next());
Map<String, Object> row = documentToMap(cursor.next());
P obj = fromRow(row);
if (obj != null) {
results.add(obj);
pager.setLastKey((String) row.get(_OBJECT_ID));
}
}
if (!results.isEmpty()) {
pager.setLastKey(results.peekLast().getId());
pager.setCount(pager.getCount() + results.size());
}
} catch (Exception e) {
Expand Down Expand Up @@ -299,30 +298,44 @@ public <P extends ParaObject> void deleteAll(String appid, List<P> objects) {
// MISC FUNCTIONS
/////////////////////////////////////////////

private <P extends ParaObject> Document toRow(P so, Class<? extends Annotation> filter) {
return toRow(so, filter, false);
private <P extends ParaObject> Document toRow(P so, Class<? extends Annotation> filter, boolean setNullFields) {
return toRow(so, filter, setNullFields, false);
}

private <P extends ParaObject> Document toRow(P so, Class<? extends Annotation> filter, boolean setNullFields) {
private <P extends ParaObject> Document toRow(P so, Class<? extends Annotation> filter,
boolean setNullFields, boolean setMongoId) {
Document row = new Document();
if (so == null) {
return row;
}
for (Entry<String, Object> entry : ParaObjectUtils.getAnnotatedFields(so, filter).entrySet()) {
// field values will be stored as they are - object structure and types will be preserved
for (Entry<String, Object> entry : ParaObjectUtils.getAnnotatedFields(so, filter, false).entrySet()) {
Object value = entry.getValue();
if ((value != null && !StringUtils.isBlank(value.toString())) || setNullFields) {
// "id" in ParaObject is translated to "_ID" mongodb
if (entry.getKey().equals(Config._ID)) {
row.put(_ID, value.toString());
} else {
row.put(entry.getKey(), (value == null) ? null : value.toString());
row.put(entry.getKey(), value);
}
if (setMongoId) {
// we add the native MongoDB id which will later be used for pagination and sorting
row.put(_OBJECT_ID, MongoDBUtils.generateNewId());
}
}
}
return row;
}

private <P extends ParaObject> P fromRow(Document row) {
return fromRow(documentToMap(row));
}

private <P extends ParaObject> P fromRow(Map<String, Object> row) {
return ParaObjectUtils.setAnnotatedFields(row);
}

private Map<String, Object> documentToMap(Document row) {
if (row == null || row.isEmpty()) {
logger.debug("row is null or empty");
return null;
Expand All @@ -336,7 +349,7 @@ private <P extends ParaObject> P fromRow(Document row) {
props.put(col.getKey(), col.getValue());
}
}
return ParaObjectUtils.setAnnotatedFields(props);
return props;
}

//////////////////////////////////////////////////////
Expand Down
16 changes: 15 additions & 1 deletion src/test/java/com/erudika/para/persistence/DAOTest.java
Expand Up @@ -27,6 +27,7 @@
import com.erudika.para.utils.Utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.junit.After;
Expand Down Expand Up @@ -123,6 +124,12 @@ public void testRead() {
assertNull(dao.read("1"));
assertNotNull(dao.read(u.getId()));
assertEquals(u.getName(), dao.read(u.getId()).getName());

// test with a custom ID
Sysprop sp = new Sysprop("email@test.com");
sp.setName("test custom id");
dao.create(sp);
assertNotNull(dao.read("email@test.com"));
}

@Test
Expand All @@ -136,9 +143,16 @@ public void testUpdate() {
assertNotNull(x.getUpdated());

// test updating locked fields
App app = new App(MongoDBUtils.generateNewId());
App app = new App("xyz");
assertNull(app.getSecret());
assertNotNull(dao.create(app));
assertNull(app.getSecret());
assertNull(((App) dao.read(app.getId())).getSecret());
app.delete();
app.create();
assertNotNull(app.getSecret());
String secret = app.getSecret();
assertNotNull(((App) dao.read(app.getId())).getSecret());
assertNotNull(secret);
app.resetSecret();
dao.update(app);
Expand Down
4 changes: 4 additions & 0 deletions src/test/java/com/erudika/para/persistence/MongoDBDAOIT.java
Expand Up @@ -30,9 +30,13 @@
*/
public class MongoDBDAOIT extends DAOTest {

private static final String APP_NAME = "para-test";

@BeforeClass
public static void setUpClass() throws InterruptedException {
System.setProperty("para.mongodb.port", "37017");
System.setProperty("para.app_name", APP_NAME);
System.setProperty("para.cluster_name", APP_NAME);
dao = new MongoDBDAO();
MongoDBUtils.createTable(Config.APP_NAME_NS);
MongoDBUtils.createTable(appid1);
Expand Down

0 comments on commit 577cdae

Please sign in to comment.