package com.celements.query; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xwiki.component.annotation.Component; import org.xwiki.component.annotation.Requirement; import org.xwiki.context.Execution; import org.xwiki.model.reference.DocumentReference; import org.xwiki.model.reference.WikiReference; import org.xwiki.query.Query; import org.xwiki.query.QueryException; import com.celements.web.service.IWebUtilsService; import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.store.XWikiHibernateBaseStore.HibernateCallback; import com.xpn.xwiki.store.XWikiHibernateStore; @Component public class QueryExecutionService implements IQueryExecutionServiceRole { private static final Logger LOGGER = LoggerFactory.getLogger(QueryExecutionService.class); @Requirement private IWebUtilsService webUtilsService; @Requirement private Execution execution; private XWikiContext getContext() { return (XWikiContext) execution.getContext().getProperty("xwikicontext"); } @Override public int executeWriteSQL(String sql) throws XWikiException { return executeWriteSQLs(Arrays.asList(sql)).get(0); } @Override public List<Integer> executeWriteSQLs(List<String> sqls) throws XWikiException { List<Integer> results = new ArrayList<Integer>(); Session session = null; try { session = getNewHibSession(); for (String sql : sqls) { results.add(executeWriteSQL(session, sql)); } } finally { if (session != null) { session.close(); } } return Collections.unmodifiableList(results); } private Session getNewHibSession() throws XWikiException { Session session = getHibStore().getSessionFactory().openSession(); getHibStore().setDatabase(session, getContext()); return session; } private int executeWriteSQL(Session session, String sql) { int result = -1; Transaction transaction = session.beginTransaction(); try { result = session.createSQLQuery(sql).executeUpdate(); } catch (HibernateException hibExc) { LOGGER.debug("error while executing sql '{}'", sql, hibExc); } finally { if (result > -1) { transaction.commit(); } else { transaction.rollback(); } } LOGGER.info("executing sql '{}' for db '{}' returned '{}'", sql, getContext().getDatabase(), result); return result; } @Override public int executeWriteHQL(String hql, Map<String, Object> binds) throws XWikiException { return executeWriteHQL(hql, binds, null); } @Override public int executeWriteHQL(String hql, Map<String, Object> binds, WikiReference wikiRef) throws XWikiException { WikiReference curWikiRef = webUtilsService.getWikiRef(); try { getContext().setDatabase(webUtilsService.getWikiRef(wikiRef).getName()); HibernateCallback<Integer> callback = new ExecuteWriteCallback(hql, binds); return getHibStore().executeWrite(getContext(), true, callback); } finally { getContext().setDatabase(curWikiRef.getName()); } } @Override public DocumentReference executeAndGetDocRef(Query query) throws QueryException { DocumentReference ret = null; List<DocumentReference> list = executeAndGetDocRefs(query); if (list.size() > 0) { ret = list.get(0); } return ret; } @Override public List<DocumentReference> executeAndGetDocRefs(Query query) throws QueryException { List<DocumentReference> ret = new ArrayList<DocumentReference>(); WikiReference wikiRef = webUtilsService.getWikiRef(); if (StringUtils.isNotBlank(query.getWiki())) { wikiRef = new WikiReference(query.getWiki()); } for (Object fullName : query.execute()) { if ((fullName instanceof String) && StringUtils.isNotBlank((String) fullName)) { ret.add(webUtilsService.resolveDocumentReference((String) fullName, wikiRef)); } else { LOGGER.debug("executeAndGetDocRefs: received invalid fullName '{}'", fullName); } } LOGGER.info("executeAndGetDocRefs: {} results for query '{}' and wiki '{}'", ret.size(), query.getStatement(), wikiRef); return ret; } private XWikiHibernateStore getHibStore() { return getContext().getWiki().getHibernateStore(); } }