/*
* Copyright (C) 2014 Divide.io
*
* 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 io.divide.dao.orientdb;
import io.divide.dao.ServerDAO;
import io.divide.shared.transitory.TransientObject;
import io.divide.shared.transitory.query.OPERAND;
import io.divide.shared.transitory.query.Query;
import io.divide.shared.transitory.query.QueryBuilder;
import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.OCommandSQL;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
import com.orientechnologies.orient.core.tx.OTransaction;
import java.security.KeyPair;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class OrientDBDao implements ServerDAO {
public static final String DEFAULT_CONFIG = "memory:default";
ODatabaseDocument db;
public OrientDBDao(){
this.db = new ODatabaseDocumentTx(DEFAULT_CONFIG);
if(this.db.exists()){
db.open("admin","admin");
} else {
db.create();
}
}
public OrientDBDao(ODatabaseDocument db){
this.db = db;
}
private void checkDb(){
ODatabaseRecordThreadLocal.INSTANCE.set(db);
}
@Override
public List<TransientObject> query(Query query) throws DAOException {
checkDb();
List<TransientObject> list = new ArrayList<TransientObject>();
OTransaction transaction = db.getTransaction();
transaction.begin();
try{
String q = query.getSQL();
System.out.println("OrientDB_Query: " + q);
if(query.getAction().equals(QueryBuilder.QueryAction.SELECT)){
List<ODocument> objects = db.query(new OSQLSynchQuery<ODocument>(q));
for(ODocument w : objects){
list.add( new ODocumentWrapper(w).toObject(TransientObject.class));
}
}
if(query.getAction().equals(QueryBuilder.QueryAction.DELETE)) {
// List<ODocument> objects = db.command(new OCommandSQL("delete from io.divide.dao.TestObject1 RETURN BEFORE")).execute();
Integer objects = db.command(new OCommandSQL(q)).execute();
TransientObject o = new EmptyTO();
o.put("count",objects);
list.add(o);
System.out.println("Delete: " + objects);
}
transaction.commit();
transaction.close();
}catch (Exception e){
transaction.rollback();
transaction.close();
}
return list;
}
@Override
public Collection<TransientObject> get(String objectType, String... keys) throws DAOException {
if(keys.length == 0) return Arrays.asList();
// String objectType = Query.safeTable(type);
checkDb();
OTransaction transaction = db.getTransaction();
transaction.begin();
// System.err.println(db.browseCluster(objectType).next());
StringBuilder sb = new StringBuilder();
sb.append("SELECT * FROM " + objectType + " WHERE ");
for(int x=0;x<keys.length;x++){
sb.append("meta_data.object_key = '" + keys[x] +"'");
if(x+1<keys.length) sb.append( " OR ");
}
List<TransientObject> objects = new ArrayList<TransientObject>();
System.err.println("Query: " + sb.toString());
List<ODocument> list = db.query(new OSQLSynchQuery<ODocument>(sb.toString()));
System.err.println("Found: " + list.size());
for(ODocument w : list){
System.err.println("Get: " + w);
TransientObject to = ODocumentWrapper.toObject(w, TransientObject.class);
objects.add(to);
}
transaction.commit();
transaction.close();
return objects;
}
@Override
public void save(TransientObject... objects) throws DAOException {
System.out.println("save: " + Arrays.asList(objects));
checkDb();
OTransaction transaction = db.getTransaction();
transaction.begin();
for(TransientObject t : objects){
db.save(new ODocumentWrapper(t));
}
transaction.commit();
transaction.close();
}
@Override
public void delete(TransientObject... objects) throws DAOException {
checkDb();
if(objects.length == 0) return;
QueryBuilder.WhereMoreBuilder builder = new QueryBuilder()
.select()
.from(objects[0].getClass())
.where(TransientObject.OBJECT_KEY, OPERAND.EQ, objects[0].getObjectKey());
for(int x=1;x<objects.length;x++){
builder.or(TransientObject.OBJECT_KEY, OPERAND.EQ, objects[x].getObjectKey());
}
Query q = builder.build();
// StringBuilder sb = new StringBuilder();
// sb.append("SELECT * FROM " + objects[0].getClass().getName() + " WHERE ");
// for(int x=0;x<objects.length;x++){
// sb.append("meta_data.object_key = '" + objects[x].getObjectKey() +"'");
// if(x+1<objects.length)
// sb.append( " OR ");
// }
System.out.println("Delete: " + q.getSQL());
List<ODocument> list = db.query(new OSQLSynchQuery<ODocument>(q.getSQL()));
for(ODocument w : list){
System.out.println("Deleting: " + w);
w.delete();
}
}
@Override
public boolean exists(TransientObject... objects) {
checkDb();
if(objects.length == 0) return false;
StringBuilder sb = new StringBuilder();
sb.append("SELECT * FROM " + Query.safeTable(objects[0].getClass()) + " WHERE ");
for(int x=0;x<objects.length;x++){
sb.append("meta_data.object_key = '" + objects[x].getObjectKey() +"'");
if(x+1<objects.length)
sb.append( " OR ");
}
List<ODocument> list = db.query(new OSQLSynchQuery<ODocument>(sb.toString()));
return objects.length == list.size();
}
@Override
public int count(String objectType) {
checkDb();
try {
return (int) db.countClass(objectType);
}catch (java.lang.IllegalArgumentException e){
return 0;
}
}
@Override
public KeyPair keys(KeyPair keys) {
return null;
}
private static class EmptyTO extends TransientObject{
protected EmptyTO() {
super(TransientObject.class);
this.meta_data.clear();
this.user_data.clear();
}
@Override
public void put(String key, Object value){
super.put(key,value);
meta_data.clear();
}
}
}