package org.wonderdb.query.parse;
/*******************************************************************************
* Copyright 2013 Vilas Athavale
*
* 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.
*******************************************************************************/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jboss.netty.buffer.ChannelBuffer;
import org.wonderdb.block.record.manager.TableRecordManager;
import org.wonderdb.cluster.Shard;
import org.wonderdb.expression.AndExpression;
import org.wonderdb.expression.VariableOperand;
import org.wonderdb.parser.TableDef;
import org.wonderdb.parser.UpdateSetExpression;
import org.wonderdb.parser.jtree.SimpleNode;
import org.wonderdb.parser.jtree.SimpleNodeHelper;
import org.wonderdb.parser.jtree.UQLParserTreeConstants;
import org.wonderdb.query.parser.jtree.DBSelectQueryJTree;
import org.wonderdb.schema.CollectionMetadata;
import org.wonderdb.schema.SchemaMetadata;
import org.wonderdb.txnlogger.LogManager;
import org.wonderdb.txnlogger.TransactionId;
import org.wonderdb.types.RecordId;
public class DBUpdateQuery extends BaseDBQuery {
AndExpression andExp = null;
SimpleNode filterNode = null;
List<CollectionAlias> caList = null;
Map<String, CollectionAlias> fromMap = null;
List<UpdateSetExpression> updateSetExpList = null;
DBSelectQueryJTree selQuery = null;
List<Integer> selectColumns = null;
public DBUpdateQuery(String q, SimpleNode query, int type, ChannelBuffer buffer) {
super(q, query, type, buffer);
SimpleNode tableNode = SimpleNodeHelper.getInstance().getFirstNode(query, UQLParserTreeConstants.JJTTABLEDEF);
List<TableDef> tDefList = new ArrayList<TableDef>();
TableDef tDef = SimpleNodeHelper.getInstance().getTableDef(tableNode);
tDefList.add(tDef);
caList = getCaList(tDefList);
fromMap = getFromMap(caList);
filterNode = SimpleNodeHelper.getInstance().getFirstNode(query, UQLParserTreeConstants.JJTFILTEREXPRESSION);
List<SimpleNode> updateSetNodes = new ArrayList<SimpleNode>();
SimpleNodeHelper.getInstance().getNodes(query, UQLParserTreeConstants.JJTUPDATECOLUMN, updateSetNodes);
updateSetExpList = SimpleNodeHelper.getInstance().getUpdateSet(updateSetNodes, caList);
List<SimpleNode> selectColumnNodeList = new ArrayList<SimpleNode>();
Map<CollectionAlias, List<Integer>> selectColumnList = new HashMap<CollectionAlias, List<Integer>>();
SimpleNodeHelper.getInstance().getNodes(query, UQLParserTreeConstants.JJTCOLUMNANDALIAS, selectColumnNodeList);
for (int i = 0; i < selectColumnNodeList.size(); i++) {
SimpleNode node = selectColumnNodeList.get(i);
VariableOperand vo = SimpleNodeHelper.getInstance().getColumnId(node, caList);
List<Integer> colList = selectColumnList.get(vo.getCollectionAlias());
if (colList == null) {
colList = new ArrayList<Integer>();
selectColumnList.put(vo.getCollectionAlias(), colList);
}
colList.add(vo.getColumnId());
}
selectColumns = selectColumnList.get(caList.get(0));
selQuery = new DBSelectQueryJTree(getQueryString(), query, fromMap, selectColumnList, filterNode, type, buffer);
andExp = selQuery.getAndExpression();
}
private List<CollectionAlias> getCaList(List<TableDef> list) {
List<CollectionAlias> retList = new ArrayList<CollectionAlias>();
for (int i = 0; i < list.size(); i++) {
TableDef tDef = list.get(i);
CollectionAlias ca = new CollectionAlias(tDef.table, tDef.alias);
retList.add(ca);
}
return retList;
}
private Map<String, CollectionAlias> getFromMap(List<CollectionAlias> caList) {
Map<String, CollectionAlias> fromMap = new HashMap<String, CollectionAlias>();
for (int i = 0; i < caList.size(); i++) {
CollectionAlias ca = caList.get(i);
fromMap.put(ca.getAlias(), ca);
}
return fromMap;
}
public AndExpression getExpression() {
return andExp;
}
public String getCollectionName() {
return caList.get(0).getCollectionName();
}
public int execute(Shard shard) {
List<Map<CollectionAlias, RecordId>> recListList = selQuery.executeGetDC(shard);
int updateCount = 0;
for (int i = 0; i < recListList.size(); i++) {
Map<CollectionAlias, RecordId> recList = recListList.get(i);
if (recList.size() == 1) {
Iterator<CollectionAlias> iter = recList.keySet().iterator();
while (iter.hasNext()) {
CollectionAlias ca = iter.next();
RecordId recId = recList.get(ca);
TransactionId txnId = null;
CollectionMetadata colMeta = SchemaMetadata.getInstance().getCollectionMetadata(ca.getCollectionName());
try {
if (colMeta.isLoggingEnabled()) {
txnId = LogManager.getInstance().startTxn();
}
updateCount = updateCount + TableRecordManager.getInstance().updateTableRecord(getCollectionName(),
recId, shard, selectColumns, updateSetExpList, queryNode, fromMap, txnId);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
LogManager.getInstance().commitTxn(txnId);
}
}
}
}
return updateCount;
}
}