Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* 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 org.camunda.bpm.engine.impl.db;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.ibatis.session.SqlSession;
import org.camunda.bpm.engine.OptimisticLockingException;
import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.ProcessEngineConfiguration;
import org.camunda.bpm.engine.ProcessEngineException;
import org.camunda.bpm.engine.WrongDbException;
import org.camunda.bpm.engine.impl.DeploymentQueryImpl;
import org.camunda.bpm.engine.impl.ExecutionQueryImpl;
import org.camunda.bpm.engine.impl.GroupQueryImpl;
import org.camunda.bpm.engine.impl.HistoricActivityInstanceQueryImpl;
import org.camunda.bpm.engine.impl.HistoricDetailQueryImpl;
import org.camunda.bpm.engine.impl.HistoricProcessInstanceQueryImpl;
import org.camunda.bpm.engine.impl.HistoricTaskInstanceQueryImpl;
import org.camunda.bpm.engine.impl.HistoricVariableInstanceQueryImpl;
import org.camunda.bpm.engine.impl.JobQueryImpl;
import org.camunda.bpm.engine.impl.Page;
import org.camunda.bpm.engine.impl.ProcessDefinitionQueryImpl;
import org.camunda.bpm.engine.impl.ProcessInstanceQueryImpl;
import org.camunda.bpm.engine.impl.TaskQueryImpl;
import org.camunda.bpm.engine.impl.UserQueryImpl;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.cmmn.entity.repository.CaseDefinitionQueryImpl;
import org.camunda.bpm.engine.impl.context.Context;
import org.camunda.bpm.engine.impl.db.upgrade.DbUpgradeStep;
import org.camunda.bpm.engine.impl.identity.db.DbGroupQueryImpl;
import org.camunda.bpm.engine.impl.identity.db.DbUserQueryImpl;
import org.camunda.bpm.engine.impl.interceptor.Session;
import org.camunda.bpm.engine.impl.persistence.entity.PropertyEntity;
import org.camunda.bpm.engine.impl.persistence.entity.VariableInstanceEntity;
import org.camunda.bpm.engine.impl.util.ClassNameUtil;
import org.camunda.bpm.engine.impl.util.IoUtil;
import org.camunda.bpm.engine.impl.util.ReflectUtil;
import org.camunda.bpm.engine.impl.variable.DeserializedObject;
/** responsibilities:
* - delayed flushing of inserts updates and deletes
* - optional dirty checking
* - db specific statement name mapping
*
* @author Tom Baeyens
* @author Joram Barrez
*/
public class DbSqlSession implements Session {
private static Logger log = Logger.getLogger(DbSqlSession.class.getName());
protected SqlSession sqlSession;
protected DbSqlSessionFactory dbSqlSessionFactory;
protected List insertedObjects = new ArrayList();
protected List updatedObjects = new ArrayList();
protected Map, Map> cachedObjects = new HashMap, Map>();
protected List bulkUpdates = new ArrayList();
protected List deleteOperations = new ArrayList();
protected List deserializedObjects = new ArrayList();
protected String connectionMetadataDefaultCatalog = null;
protected String connectionMetadataDefaultSchema = null;
public DbSqlSession(DbSqlSessionFactory dbSqlSessionFactory) {
this.dbSqlSessionFactory = dbSqlSessionFactory;
this.sqlSession = dbSqlSessionFactory
.getSqlSessionFactory()
.openSession();
}
public DbSqlSession(DbSqlSessionFactory dbSqlSessionFactory, Connection connection, String catalog, String schema) {
this.dbSqlSessionFactory = dbSqlSessionFactory;
this.sqlSession = dbSqlSessionFactory
.getSqlSessionFactory()
.openSession(connection);
this.connectionMetadataDefaultCatalog = catalog;
this.connectionMetadataDefaultSchema = schema;
}
// insert ///////////////////////////////////////////////////////////////////
/**
* Inserts a object at the given index in the insert objects list. If the
* index is -1 it will inserted at the end of the list.
*
* @param persistentObject the object to insert
* @param index the index at which the object should be inserted or -1 for the end of the list
*/
public void insertAt(PersistentObject persistentObject, int index) {
if (persistentObject.getId()==null) {
String id = dbSqlSessionFactory.getIdGenerator().getNextId();
persistentObject.setId(id);
}
if (index == -1) {
index = insertedObjects.size();
}
insertedObjects.add(index, persistentObject);
cachePut(persistentObject, false);
}
public void insert(PersistentObject persistentObject) {
insertAt(persistentObject, -1);
}
public void insertBefore(PersistentObject objectToInsert, PersistentObject referenceObject) {
int index = insertedObjects.indexOf(referenceObject);
insertAt(objectToInsert, index);
}
// update ///////////////////////////////////////////////////////////////////
public void update(PersistentObject persistentObject) {
updatedObjects.add(persistentObject);
cachePut(persistentObject, false);
}
// delete ///////////////////////////////////////////////////////////////////
// public void delete(Class> persistentObjectClass, String persistentObjectId) {
// for (DeleteOperation deleteOperation: deleteOperations) {
// if (deleteOperation instanceof DeleteById) {
// DeleteById deleteById = (DeleteById) deleteOperation;
// if ( persistentObjectClass.equals(deleteById.persistenceObjectClass)
// && persistentObjectId.equals(deleteById.persistentObjectId)
// ) {
// // skip this delete
// return;
// }
// }
// }
// deleteOperations.add(new DeleteById(persistentObjectClass, persistentObjectId));
// }
public interface DeleteOperation {
void execute();
}
// public class DeleteById implements DeleteOperation {
// Class> persistenceObjectClass;
// String persistentObjectId;
// public DeleteById(Class< ? > clazz, String id) {
// this.persistenceObjectClass = clazz;
// this.persistentObjectId = id;
// }
// public void execute() {
// String deleteStatement = dbSqlSessionFactory.getDeleteStatement(persistenceObjectClass);
// deleteStatement = dbSqlSessionFactory.mapStatement(deleteStatement);
// if (deleteStatement==null) {
// throw new ProcessEngineException("no delete statement for "+persistenceObjectClass+" in the ibatis mapping files");
// }
// log.fine("deleting: "+ClassNameUtil.getClassNameWithoutPackage(persistenceObjectClass)+"["+persistentObjectId+"]");
// sqlSession.delete(deleteStatement, persistentObjectId);
// }
// public String toString() {
// return "delete "+ClassNameUtil.getClassNameWithoutPackage(persistenceObjectClass)+"["+persistentObjectId+"]";
// }
// }
public void delete(String statement, Object parameter) {
deleteOperations.add(new BulkDeleteOperation(statement, parameter));
}
public void update(String statement, Object parameter) {
BulkUpdateOperation updateOperation = new BulkUpdateOperation(statement, parameter);
bulkUpdates.add(updateOperation);
}
/**
* Use this {@link DeleteOperation} to execute a dedicated delete statement.
* It is important to note there won't be any optimistic locking checks done
* for these kind of delete operations!
*
* For example, a usage of this operation would be to delete all variables for
* a certain execution, when that certain execution is removed. The optimistic locking
* happens on the execution, but the variables can be removed by a simple
* 'delete from var_table where execution_id is xxx'. It could very well be there
* are no variables, which would also work with this query, but not with the
* regular {@link DeletePersistentObjectOperation} operation.
*/
public class BulkDeleteOperation implements DeleteOperation {
String statement;
Object parameter;
public BulkDeleteOperation(String statement, Object parameter) {
this.statement = dbSqlSessionFactory.mapStatement(statement);
this.parameter = parameter;
}
public void execute() {
sqlSession.delete(statement, parameter);
}
public String toString() {
return "bulk delete: "+statement;
}
}
public class BulkUpdateOperation {
String statement;
Object parameter;
public BulkUpdateOperation(String statement, Object parameter) {
this.statement = statement;
this.parameter = parameter;
}
public String getStatement() {
return statement;
}
public Object getParameter() {
return parameter;
}
}
public void delete(PersistentObject persistentObject) {
for (DeleteOperation deleteOperation: deleteOperations) {
if (deleteOperation instanceof DeletePersistentObjectOperation) {
DeletePersistentObjectOperation deletePersistentObjectOperation = (DeletePersistentObjectOperation) deleteOperation;
if (persistentObject.getId().equals(deletePersistentObjectOperation.getPersistentObject().getId())
&& persistentObject.getClass().equals(deletePersistentObjectOperation.getPersistentObject().getClass())) {
return; // Skip this delete. It was already added.
}
}
}
deleteOperations.add(new DeletePersistentObjectOperation(persistentObject));
}
/**
* A {@link DeleteOperation} used when the persistent object has been fetched already.
*/
public class DeletePersistentObjectOperation implements DeleteOperation {
protected PersistentObject persistentObject;
public DeletePersistentObjectOperation(PersistentObject persistentObject) {
this.persistentObject = persistentObject;
}
public void execute() {
String deleteStatement = dbSqlSessionFactory.getDeleteStatement(persistentObject.getClass());
deleteStatement = dbSqlSessionFactory.mapStatement(deleteStatement);
if (deleteStatement == null) {
throw new ProcessEngineException("no delete statement for " + persistentObject.getClass() + " in the ibatis mapping files");
}
log.fine("deleting: " + ClassNameUtil.getClassNameWithoutPackage(persistentObject.getClass()) + "[" + persistentObject.getId() + "]");
// It only makes sense to check for optimistic locking exceptions for objects that actually have a revision
if (persistentObject instanceof HasRevision) {
int nrOfRowsDeleted = sqlSession.delete(deleteStatement, persistentObject);
if (nrOfRowsDeleted == 0) {
throw new OptimisticLockingException(DbSqlSession.this.toString(persistentObject) + " was updated by another transaction concurrently");
}
} else {
sqlSession.delete(deleteStatement, persistentObject);
}
}
public PersistentObject getPersistentObject() {
return persistentObject;
}
public void setPersistentObject(PersistentObject persistentObject) {
this.persistentObject = persistentObject;
}
public String toString() {
return "Delete operation for " + persistentObject.getClass() + " [" + persistentObject.getId() + "]";
}
}
// select ///////////////////////////////////////////////////////////////////
@SuppressWarnings("unchecked")
public List selectList(String statement) {
return selectList(statement, null, 0, Integer.MAX_VALUE);
}
@SuppressWarnings("unchecked")
public List selectList(String statement, Object parameter) {
return selectList(statement, parameter, 0, Integer.MAX_VALUE);
}
@SuppressWarnings("unchecked")
public List selectList(String statement, Object parameter, Page page) {
if(page!=null) {
return selectList(statement, parameter, page.getFirstResult(), page.getMaxResults());
}else {
return selectList(statement, parameter, 0, Integer.MAX_VALUE);
}
}
@SuppressWarnings("unchecked")
public List selectList(String statement, ListQueryParameterObject parameter, Page page) {
return selectList(statement, parameter);
}
@SuppressWarnings("unchecked")
public List selectList(String statement, Object parameter, int firstResult, int maxResults) {
return selectList(statement, new ListQueryParameterObject(parameter, firstResult, maxResults));
}
@SuppressWarnings("unchecked")
public List selectList(String statement, ListQueryParameterObject parameter) {
return selectListWithRawParameter(statement, parameter, parameter.getFirstResult(), parameter.getMaxResults());
}
@SuppressWarnings("unchecked")
public List selectListWithRawParameter(String statement, Object parameter, int firstResult, int maxResults) {
statement = dbSqlSessionFactory.mapStatement(statement);
if(firstResult == -1 || maxResults==-1) {
return Collections.EMPTY_LIST;
}
List loadedObjects = sqlSession.selectList(statement, parameter);
return filterLoadedObjects(loadedObjects);
}
public Object selectOne(String statement, Object parameter) {
statement = dbSqlSessionFactory.mapStatement(statement);
Object result = sqlSession.selectOne(statement, parameter);
if (result instanceof PersistentObject) {
PersistentObject loadedObject = (PersistentObject) result;
result = cacheFilter(loadedObject);
}
return result;
}
public boolean selectBoolean(String statement, Object parameter) {
statement = dbSqlSessionFactory.mapStatement(statement);
List result = sqlSession.selectList(statement, parameter);
if(result != null) {
return result.contains(1);
}
return false;
}
@SuppressWarnings("unchecked")
public T selectById(Class entityClass, String id) {
T persistentObject = cacheGet(entityClass, id);
if (persistentObject!=null) {
return persistentObject;
}
String selectStatement = dbSqlSessionFactory.getSelectStatement(entityClass);
selectStatement = dbSqlSessionFactory.mapStatement(selectStatement);
persistentObject = (T) sqlSession.selectOne(selectStatement, id);
if (persistentObject==null) {
return null;
}
cachePut(persistentObject, true);
return persistentObject;
}
// internal session cache ///////////////////////////////////////////////////
@SuppressWarnings("unchecked")
protected List filterLoadedObjects(List