2 Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 package com.mysql.clusterj.tie;
20 import java.math.BigDecimal;
21 import java.math.BigInteger;
22 import java.nio.ByteBuffer;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.List;
27 import com.mysql.clusterj.core.store.Blob;
28 import com.mysql.clusterj.core.store.Column;
29 import com.mysql.clusterj.core.store.Operation;
30 import com.mysql.clusterj.core.store.ResultData;
31 import com.mysql.clusterj.core.store.Table;
33 import com.mysql.clusterj.core.util.I18NHelper;
34 import com.mysql.clusterj.core.util.Logger;
35 import com.mysql.clusterj.core.util.LoggerFactoryService;
36 import com.mysql.clusterj.tie.DbImpl.BufferManager;
38 import com.mysql.ndbjtie.ndbapi.NdbBlob;
39 import com.mysql.ndbjtie.ndbapi.NdbOperation;
44 class OperationImpl implements Operation {
46 /** My message translator */
47 static final I18NHelper local = I18NHelper
48 .getInstance(OperationImpl.class);
51 static final Logger logger = LoggerFactoryService.getFactory()
52 .getInstance(OperationImpl.class);
54 private NdbOperation ndbOperation;
56 protected List<Column> storeColumns = new ArrayList<Column>();
58 protected ClusterTransactionImpl clusterTransaction;
60 /** The size of the receive buffer for this operation (may be zero for non-read operations) */
61 protected int bufferSize;
63 /** The maximum column id for this operation (may be zero for non-read operations) */
64 protected int maximumColumnId;
66 /** The offsets into the buffer for each column (may be null for non-read operations) */
67 protected int[] offsets;
69 /** The lengths of fields in the buffer for each column (may be null for non-read operations) */
70 protected int[] lengths;
72 /** The maximum length of any column in this operation */
73 protected int maximumColumnLength;
75 protected BufferManager bufferManager;
77 /** Constructor used for insert and delete operations that do not need to read data.
79 * @param operation the operation
80 * @param transaction the transaction
82 public OperationImpl(NdbOperation operation, ClusterTransactionImpl transaction) {
83 this.ndbOperation = operation;
84 this.clusterTransaction = transaction;
85 this.bufferManager = clusterTransaction.getBufferManager();
88 /** Constructor used for read operations. The table is used to obtain data used
89 * to lay out memory for the result.
90 * @param storeTable the table
91 * @param operation the operation
92 * @param transaction the transaction
94 public OperationImpl(Table storeTable, NdbOperation operation, ClusterTransactionImpl transaction) {
95 this(operation, transaction);
96 TableImpl tableImpl = (TableImpl)storeTable;
97 this.maximumColumnId = tableImpl.getMaximumColumnId();
98 this.bufferSize = tableImpl.getBufferSize();
99 this.offsets = tableImpl.getOffsets();
100 this.lengths = tableImpl.getLengths();
101 this.maximumColumnLength = tableImpl.getMaximumColumnLength();
104 public void equalBigInteger(Column storeColumn, BigInteger value) {
105 ByteBuffer buffer = Utility.convertValue(storeColumn, value);
106 int returnCode = ndbOperation.equal(storeColumn.getName(), buffer);
107 handleError(returnCode, ndbOperation);
110 public void equalBoolean(Column storeColumn, boolean booleanValue) {
111 byte value = (booleanValue?(byte)0x01:(byte)0x00);
112 int returnCode = ndbOperation.equal(storeColumn.getName(), value);
113 handleError(returnCode, ndbOperation);
116 public void equalByte(Column storeColumn, byte value) {
117 int storeValue = Utility.convertByteValueForStorage(storeColumn, value);
118 int returnCode = ndbOperation.equal(storeColumn.getName(), storeValue);
119 handleError(returnCode, ndbOperation);
122 public void equalBytes(Column storeColumn, byte[] value) {
123 if (logger.isDetailEnabled()) logger.detail("Column: " + storeColumn.getName() + " columnId: " + storeColumn.getColumnId() + " data length: " + value.length);
124 ByteBuffer buffer = Utility.convertValue(storeColumn, value);
125 int returnCode = ndbOperation.equal(storeColumn.getName(), buffer);
126 handleError(returnCode, ndbOperation);
129 public void equalDecimal(Column storeColumn, BigDecimal value) {
130 ByteBuffer buffer = Utility.convertValue(storeColumn, value);
131 int returnCode = ndbOperation.equal(storeColumn.getName(), buffer);
132 handleError(returnCode, ndbOperation);
135 public void equalDouble(Column storeColumn, double value) {
136 ByteBuffer buffer = Utility.convertValue(storeColumn, value);
137 int returnCode = ndbOperation.equal(storeColumn.getName(), buffer);
138 handleError(returnCode, ndbOperation);
141 public void equalFloat(Column storeColumn, float value) {
142 ByteBuffer buffer = Utility.convertValue(storeColumn, value);
143 int returnCode = ndbOperation.equal(storeColumn.getName(), buffer);
144 handleError(returnCode, ndbOperation);
147 public void equalInt(Column storeColumn, int value) {
148 int returnCode = ndbOperation.equal(storeColumn.getName(), value);
149 handleError(returnCode, ndbOperation);
152 public void equalShort(Column storeColumn, short value) {
153 int storeValue = Utility.convertShortValueForStorage(storeColumn, value);
154 int returnCode = ndbOperation.equal(storeColumn.getName(), storeValue);
155 handleError(returnCode, ndbOperation);
158 public void equalLong(Column storeColumn, long value) {
159 long storeValue = Utility.convertLongValueForStorage(storeColumn, value);
160 int returnCode = ndbOperation.equal(storeColumn.getName(), storeValue);
161 handleError(returnCode, ndbOperation);
164 public void equalString(Column storeColumn, String value) {
165 ByteBuffer stringStorageBuffer = Utility.encode(value, storeColumn, bufferManager);
166 int returnCode = ndbOperation.equal(storeColumn.getName(), stringStorageBuffer);
167 bufferManager.clearStringStorageBuffer();
168 handleError(returnCode, ndbOperation);
171 public void getBlob(Column storeColumn) {
172 NdbBlob ndbBlob = ndbOperation.getBlobHandleM(storeColumn.getColumnId());
173 handleError(ndbBlob, ndbOperation);
176 public Blob getBlobHandle(Column storeColumn) {
177 NdbBlob blobHandle = ndbOperation.getBlobHandleM(storeColumn.getColumnId());
178 handleError(blobHandle, ndbOperation);
179 return new BlobImpl(blobHandle);
182 /** Specify the columns to be used for the operation.
183 * For now, just save the columns. When resultData is called, pass the columns
184 * to the ResultData constructor and then execute the operation.
187 public void getValue(Column storeColumn) {
188 storeColumns.add(storeColumn);
191 public void postExecuteCallback(Runnable callback) {
192 clusterTransaction.postExecuteCallback(callback);
195 /** Construct a new ResultData using the saved column data and then execute the operation.
198 public ResultData resultData() {
199 return resultData(true);
202 /** Construct a new ResultData and if requested, execute the operation.
205 public ResultData resultData(boolean execute) {
206 if (logger.isDetailEnabled()) logger.detail("storeColumns: " + Arrays.toString(storeColumns.toArray()));
207 ResultDataImpl result;
209 result = new ResultDataImpl(ndbOperation, storeColumns, maximumColumnId, bufferSize,
210 offsets, lengths, bufferManager, false);
211 clusterTransaction.executeNoCommit(false, true);
213 result = new ResultDataImpl(ndbOperation, storeColumns, maximumColumnId, bufferSize,
214 offsets, lengths, bufferManager, true);
219 public void setBigInteger(Column storeColumn, BigInteger value) {
220 ByteBuffer buffer = Utility.convertValue(storeColumn, value);
221 int returnCode = ndbOperation.setValue(storeColumn.getColumnId(), buffer);
222 handleError(returnCode, ndbOperation);
225 public void setBoolean(Column storeColumn, Boolean value) {
226 byte byteValue = (value?(byte)0x01:(byte)0x00);
227 setByte(storeColumn, byteValue);
230 public void setByte(Column storeColumn, byte value) {
231 int storeValue = Utility.convertByteValueForStorage(storeColumn, value);
232 int returnCode = ndbOperation.setValue(storeColumn.getColumnId(), storeValue);
233 handleError(returnCode, ndbOperation);
236 public void setBytes(Column storeColumn, byte[] value) {
237 // TODO use the string storage buffer instead of allocating a new buffer for each value
238 ByteBuffer buffer = Utility.convertValue(storeColumn, value);
239 int returnCode = ndbOperation.setValue(storeColumn.getColumnId(), buffer);
240 handleError(returnCode, ndbOperation);
243 public void setDecimal(Column storeColumn, BigDecimal value) {
244 ByteBuffer buffer = Utility.convertValue(storeColumn, value);
245 int returnCode = ndbOperation.setValue(storeColumn.getColumnId(), buffer);
246 handleError(returnCode, ndbOperation);
249 public void setDouble(Column storeColumn, Double value) {
250 int returnCode = ndbOperation.setValue(storeColumn.getColumnId(), value);
251 handleError(returnCode, ndbOperation);
254 public void setFloat(Column storeColumn, Float value) {
255 int returnCode = ndbOperation.setValue(storeColumn.getColumnId(), value);
256 handleError(returnCode, ndbOperation);
259 public void setInt(Column storeColumn, Integer value) {
260 int returnCode = ndbOperation.setValue(storeColumn.getColumnId(), value);
261 handleError(returnCode, ndbOperation);
264 public void setLong(Column storeColumn, long value) {
265 long storeValue = Utility.convertLongValueForStorage(storeColumn, value);
266 int returnCode = ndbOperation.setValue(storeColumn.getName(), storeValue);
267 handleError(returnCode, ndbOperation);
270 public void setNull(Column storeColumn) {
271 int returnCode = ndbOperation.setValue(storeColumn.getColumnId(), null);
272 handleError(returnCode, ndbOperation);
275 public void setShort(Column storeColumn, Short value) {
276 int storeValue = Utility.convertShortValueForStorage(storeColumn, value);
277 int returnCode = ndbOperation.setValue(storeColumn.getName(), storeValue);
278 handleError(returnCode, ndbOperation);
281 public void setString(Column storeColumn, String value) {
282 ByteBuffer stringStorageBuffer = Utility.encode(value, storeColumn, bufferManager);
283 int returnCode = ndbOperation.setValue(storeColumn.getColumnId(), stringStorageBuffer);
284 bufferManager.clearStringStorageBuffer();
285 handleError(returnCode, ndbOperation);
288 public int errorCode() {
289 return ndbOperation.getNdbError().code();
292 protected void handleError(int returnCode, NdbOperation ndbOperation) {
293 if (returnCode == 0) {
296 Utility.throwError(returnCode, ndbOperation.getNdbError());
300 protected static void handleError(Object object, NdbOperation ndbOperation) {
301 if (object != null) {
304 Utility.throwError(null, ndbOperation.getNdbError());