001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.command.dml;
007:
008: import java.sql.SQLException;
009:
010: import org.h2.command.Command;
011: import org.h2.command.Prepared;
012: import org.h2.constant.ErrorCode;
013: import org.h2.engine.Right;
014: import org.h2.engine.Session;
015: import org.h2.expression.Expression;
016: import org.h2.log.UndoLogRecord;
017: import org.h2.message.Message;
018: import org.h2.result.LocalResult;
019: import org.h2.result.Row;
020: import org.h2.table.Column;
021: import org.h2.table.Table;
022: import org.h2.util.ObjectArray;
023: import org.h2.value.Value;
024:
025: /**
026: * This class represents the statement
027: * INSERT
028: */
029: public class Insert extends Prepared {
030:
031: private Table table;
032: private Column[] columns;
033: private ObjectArray list = new ObjectArray();
034: private Query query;
035:
036: public Insert(Session session) {
037: super (session);
038: }
039:
040: public void setCommand(Command command) {
041: super .setCommand(command);
042: if (query != null) {
043: query.setCommand(command);
044: }
045: }
046:
047: public void setTable(Table table) {
048: this .table = table;
049: }
050:
051: public void setColumns(Column[] columns) {
052: this .columns = columns;
053: }
054:
055: public void setQuery(Query query) {
056: this .query = query;
057: }
058:
059: public void addRow(Expression[] expr) {
060: list.add(expr);
061: }
062:
063: public int update() throws SQLException {
064: int count;
065: session.getUser().checkRight(table, Right.INSERT);
066: setCurrentRowNumber(0);
067: if (list.size() > 0) {
068: count = 0;
069: for (int x = 0; x < list.size(); x++) {
070: Expression[] expr = (Expression[]) list.get(x);
071: Row newRow = table.getTemplateRow();
072: setCurrentRowNumber(x + 1);
073: for (int i = 0; i < columns.length; i++) {
074: Column c = columns[i];
075: int index = c.getColumnId();
076: Expression e = expr[i];
077: if (e != null) {
078: // e can be null (DEFAULT)
079: e = e.optimize(session);
080: Value v = e.getValue(session).convertTo(
081: c.getType());
082: newRow.setValue(index, v);
083: }
084: }
085: checkCancelled();
086: table.fireBefore(session);
087: table.validateConvertUpdateSequence(session, newRow);
088: table.fireBeforeRow(session, null, newRow);
089: table.lock(session, true, false);
090: table.addRow(session, newRow);
091: session.log(table, UndoLogRecord.INSERT, newRow);
092: table.fireAfter(session);
093: table.fireAfterRow(session, null, newRow);
094: count++;
095: }
096: } else {
097: LocalResult rows = query.query(0);
098: count = 0;
099: table.fireBefore(session);
100: table.lock(session, true, false);
101: while (rows.next()) {
102: checkCancelled();
103: count++;
104: Value[] r = rows.currentRow();
105: Row newRow = table.getTemplateRow();
106: setCurrentRowNumber(count);
107: for (int j = 0; j < columns.length; j++) {
108: Column c = columns[j];
109: int index = c.getColumnId();
110: Value v = r[j].convertTo(c.getType());
111: newRow.setValue(index, v);
112: }
113: table.validateConvertUpdateSequence(session, newRow);
114: table.fireBeforeRow(session, null, newRow);
115: table.addRow(session, newRow);
116: session.log(table, UndoLogRecord.INSERT, newRow);
117: table.fireAfterRow(session, null, newRow);
118: }
119: rows.close();
120: table.fireAfter(session);
121: }
122: return count;
123: }
124:
125: public String getPlanSQL() {
126: StringBuffer buff = new StringBuffer();
127: buff.append("INSERT INTO ");
128: buff.append(table.getSQL());
129: buff.append('(');
130: for (int i = 0; i < columns.length; i++) {
131: if (i > 0) {
132: buff.append(", ");
133: }
134: buff.append(columns[i].getSQL());
135: }
136: buff.append(")\n");
137: if (list.size() > 0) {
138: buff.append("VALUES ");
139: for (int x = 0; x < list.size(); x++) {
140: Expression[] expr = (Expression[]) list.get(x);
141: if (x > 0) {
142: buff.append(", ");
143: }
144: buff.append("(");
145: for (int i = 0; i < columns.length; i++) {
146: if (i > 0) {
147: buff.append(", ");
148: }
149: Expression e = expr[i];
150: if (e == null) {
151: buff.append("DEFAULT");
152: } else {
153: buff.append(e.getSQL());
154: }
155: }
156: buff.append(')');
157: }
158: } else {
159: buff.append(query.getPlanSQL());
160: }
161: return buff.toString();
162: }
163:
164: public void prepare() throws SQLException {
165: if (columns == null) {
166: if (list.size() > 0
167: && ((Expression[]) list.get(0)).length == 0) {
168: // special case where table is used as a sequence
169: columns = new Column[0];
170: } else {
171: columns = table.getColumns();
172: }
173: }
174: if (list.size() > 0) {
175: for (int x = 0; x < list.size(); x++) {
176: Expression[] expr = (Expression[]) list.get(x);
177: if (expr.length != columns.length) {
178: throw Message
179: .getSQLException(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
180: }
181: for (int i = 0; i < expr.length; i++) {
182: Expression e = expr[i];
183: if (e != null) {
184: expr[i] = e.optimize(session);
185: }
186: }
187: }
188: } else {
189: query.prepare();
190: if (query.getColumnCount() != columns.length) {
191: throw Message
192: .getSQLException(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
193: }
194: }
195: }
196:
197: public boolean isTransactional() {
198: return true;
199: }
200:
201: public LocalResult queryMeta() {
202: return null;
203: }
204:
205: }
|