/* * Copyright 2014-2015 the original author or authors * * 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 com.wplatform.ddal.excutor.dml; import java.util.ArrayList; import java.util.List; import com.wplatform.ddal.command.Prepared; import com.wplatform.ddal.command.dml.Insert; import com.wplatform.ddal.command.dml.Query; import com.wplatform.ddal.command.expression.Expression; import com.wplatform.ddal.dbobject.Right; import com.wplatform.ddal.dbobject.table.Column; import com.wplatform.ddal.dbobject.table.TableMate; import com.wplatform.ddal.dispatch.rule.TableNode; import com.wplatform.ddal.message.DbException; import com.wplatform.ddal.result.ResultInterface; import com.wplatform.ddal.result.ResultTarget; import com.wplatform.ddal.result.Row; import com.wplatform.ddal.result.SearchRow; import com.wplatform.ddal.util.New; import com.wplatform.ddal.util.StatementBuilder; import com.wplatform.ddal.value.Value; /** * @author <a href="mailto:jorgie.mail@gmail.com">jorgie li</a> * TODO validation rule column */ public class InsertExecutor extends PreparedRoutingExecutor<Insert> implements ResultTarget { private int rowNumber; private int affectRows; private List<Row> newRows = New.arrayList(10); /** * @param prepared */ public InsertExecutor(Insert prepared) { super(prepared); } @Override public int executeUpdate() { TableMate table = castTableMate(prepared.getTable()); table.check(); session.getUser().checkRight(table, Right.INSERT); prepared.setCurrentRowNumber(0); rowNumber = 0; affectRows = 0; ArrayList<Expression[]> list = prepared.getList(); Column[] columns = prepared.getColumns(); int listSize = list.size(); if (listSize > 0) { int columnLen = columns.length; for (int x = 0; x < listSize; x++) { Row newRow = table.getTemplateRow(); Expression[] expr = list.get(x); prepared.setCurrentRowNumber(x + 1); for (int i = 0; i < columnLen; i++) { Column c = columns[i]; int index = c.getColumnId(); Expression e = expr[i]; if (e != null) { // e can be null (DEFAULT) e = e.optimize(session); try { Value v = c.convert(e.getValue(session)); newRow.setValue(index, v); } catch (DbException ex) { throw prepared.setRow(ex, x, Prepared.getSQL(expr)); } } } rowNumber++; table.validateConvertUpdateSequence(session, newRow); addNewRow(newRow); } } else { Query query = prepared.getQuery(); if (prepared.isInsertFromSelect()) { query.query(0, this); } else { ResultInterface rows = query.query(0); while (rows.next()) { Value[] r = rows.currentRow(); addRow(r); } rows.close(); } } flushNewRows(); return affectRows; } @Override public void addRow(Value[] values) { TableMate table = castTableMate(prepared.getTable()); Row newRow = table.getTemplateRow(); Column[] columns = prepared.getColumns(); prepared.setCurrentRowNumber(++rowNumber); for (int j = 0, len = columns.length; j < len; j++) { Column c = columns[j]; int index = c.getColumnId(); try { Value v = c.convert(values[j]); newRow.setValue(index, v); } catch (DbException ex) { throw prepared.setRow(ex, rowNumber, Prepared.getSQL(values)); } } table.validateConvertUpdateSequence(session, newRow); addNewRow(newRow); } @Override public int getRowCount() { return rowNumber; } private void addNewRow(Row newRow) { newRows.add(newRow); if (newRows.size() >= 200) { flushNewRows(); } } private void flushNewRows() { try { TableMate table = castTableMate(prepared.getTable()); if (newRows.isEmpty()) { return; } else if (newRows.size() == 1) { affectRows += updateRow(table, newRows.get(0)); } else { affectRows += updateRows(table, newRows); } } finally { newRows.clear(); } } @Override protected List<Value> doTranslate(TableNode node, SearchRow row, StatementBuilder buff) { String forTable = node.getCompositeObjectName(); TableMate table = castTableMate(prepared.getTable()); Column[] columns = table.getColumns(); return buildInsert(forTable, columns, row, buff); } }