MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ResultDataImpl.java
1 /*
2  Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
3 
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.
7 
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.
12 
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
16  */
17 
18 package com.mysql.clusterj.tie;
19 
20 import java.math.BigDecimal;
21 import java.math.BigInteger;
22 
23 import java.nio.ByteBuffer;
24 import java.nio.ByteOrder;
25 
26 import java.util.List;
27 
28 import com.mysql.clusterj.ClusterJFatalInternalException;
29 
30 import com.mysql.clusterj.core.store.Blob;
31 import com.mysql.clusterj.core.store.Column;
32 import com.mysql.clusterj.core.store.ResultData;
33 
34 import com.mysql.clusterj.core.util.I18NHelper;
35 import com.mysql.clusterj.core.util.Logger;
36 import com.mysql.clusterj.core.util.LoggerFactoryService;
37 import com.mysql.clusterj.tie.DbImpl.BufferManager;
38 
39 import com.mysql.ndbjtie.ndbapi.NdbBlob;
40 import com.mysql.ndbjtie.ndbapi.NdbErrorConst;
41 import com.mysql.ndbjtie.ndbapi.NdbOperation;
42 import com.mysql.ndbjtie.ndbapi.NdbRecAttr;
43 
47 class ResultDataImpl implements ResultData {
48 
50  static final I18NHelper local = I18NHelper
51  .getInstance(ResultDataImpl.class);
52 
54  static final Logger logger = LoggerFactoryService.getFactory()
55  .getInstance(ResultDataImpl.class);
56 
58  protected final int RESULT_READY = 0;
59  protected final int SCAN_FINISHED = 1;
60  protected final int CACHE_EMPTY = 2;
61 
63  private NdbOperation ndbOperation = null;
64 
66  private NdbRecAttr[] ndbRecAttrs = null;
67 
69  private boolean nextDone;
70 
72  private ByteBuffer byteBuffer = null;
73 
75  private int[] offsets = null;
76 
78  private int[] lengths = null;
79 
81  private final Column[] storeColumns;
82 
84  private BufferManager bufferManager;
85 
97  public ResultDataImpl(NdbOperation ndbOperation, List<Column> storeColumns,
98  int maximumColumnId, int bufferSize, int[] offsets, int[] lengths,
99  BufferManager bufferManager, boolean allocateNew) {
100  this.ndbOperation = ndbOperation;
101  this.bufferManager = bufferManager;
102  // save the column list
103  this.storeColumns = storeColumns.toArray(new Column[storeColumns.size()]);
104  this.offsets = offsets;
105  this.lengths = lengths;
106  if (allocateNew) {
107  byteBuffer = ByteBuffer.allocateDirect(bufferSize);
108  } else {
109  byteBuffer = bufferManager.getResultDataBuffer(bufferSize);
110  }
111  byteBuffer.order(ByteOrder.nativeOrder());
112  // iterate the list of store columns and allocate an NdbRecAttr (via getValue) for each
113  ndbRecAttrs = new NdbRecAttr[maximumColumnId + 1];
114  for (Column storeColumn: storeColumns) {
115  NdbRecAttr ndbRecAttr = null;
116  int columnId = storeColumn.getColumnId();
117  byteBuffer.position(offsets[columnId]);
118  if (lengths[columnId] == 0) {
119  // TODO: to help profiling
120  ndbRecAttr = ndbOperation.getValue(columnId, null);
121 // ndbRecAttr = getValue(ndbOperation, columnId, null);
122  } else {
123  ndbRecAttr = ndbOperation.getValue(columnId, byteBuffer);
124 // ndbRecAttr = getValue(ndbOperation, columnId, byteBuffer);
125  }
126  handleError(ndbRecAttr, ndbOperation);
127  ndbRecAttrs[columnId] = ndbRecAttr;
128  }
129  }
130 
131  private NdbRecAttr getValue(NdbOperation ndbOperation2, int columnId,
132  ByteBuffer byteBuffer2) {
133  // TODO: to help profiling
134  return ndbOperation2.getValue(columnId, byteBuffer2);
135  }
136 
137  public boolean next() {
138  // NdbOperation has exactly zero or one result. ScanResultDataImpl handles scans...
139  NdbErrorConst error = ndbOperation.getNdbError();
140  // if the ndbOperation reports an error there is no result
141  int errorCode = error.code();
142  if (errorCode != 0) {
143  setNoResult();
144  }
145  if (nextDone) {
146  return false;
147  } else {
148  nextDone = true;
149  return true;
150  }
151  }
152 
153  public Blob getBlob(int column) {
154  return getBlob(storeColumns[column]);
155  }
156 
157  public Blob getBlob(Column storeColumn) {
158  NdbBlob ndbBlob = ndbOperation.getBlobHandle(storeColumn.getColumnId());
159  handleError(ndbBlob, ndbOperation);
160  return new BlobImpl(ndbBlob);
161  }
162 
163  public boolean getBoolean(int column) {
164  return getBoolean(storeColumns[column]);
165  }
166 
167  public boolean getBoolean(Column storeColumn) {
168  int index = storeColumn.getColumnId();
169  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
170  return Utility.getBoolean(storeColumn, ndbRecAttr);
171  }
172 
173  public boolean[] getBooleans(int column) {
174  return getBooleans(storeColumns[column]);
175  }
176 
177  public boolean[] getBooleans(Column storeColumn) {
178  throw new ClusterJFatalInternalException(local.message("ERR_Not_Implemented"));
179  }
180 
181  public byte getByte(int column) {
182  return getByte(storeColumns[column]);
183  }
184 
185  public byte getByte(Column storeColumn) {
186  int index = storeColumn.getColumnId();
187  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
188  return Utility.getByte(storeColumn, ndbRecAttr);
189  }
190 
191  public short getShort(int column) {
192  return getShort(storeColumns[column]);
193  }
194 
195  public short getShort(Column storeColumn) {
196  int index = storeColumn.getColumnId();
197  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
198  return Utility.getShort(storeColumn, ndbRecAttr);
199  }
200 
201  public int getInt(int column) {
202  return getInt(storeColumns[column]);
203  }
204 
205  public int getInt(Column storeColumn) {
206  int index = storeColumn.getColumnId();
207  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
208  return Utility.getInt(storeColumn, ndbRecAttr);
209  }
210 
211  public long getLong(int column) {
212  return getLong(storeColumns[column]);
213  }
214 
215  public long getLong(Column storeColumn) {
216  int index = storeColumn.getColumnId();
217  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
218  return Utility.getLong(storeColumn, ndbRecAttr);
219  }
220 
221  public float getFloat(int column) {
222  return getFloat(storeColumns[column]);
223  }
224 
225  public float getFloat(Column storeColumn) {
226  int index = storeColumn.getColumnId();
227  float result = ndbRecAttrs[index].float_value();
228  return result;
229  }
230 
231  public double getDouble(int column) {
232  return getDouble(storeColumns[column]);
233  }
234 
235  public double getDouble(Column storeColumn) {
236  int index = storeColumn.getColumnId();
237  double result = ndbRecAttrs[index].double_value();
238  return result;
239  }
240 
241  public String getString(int column) {
242  return getString(storeColumns[column]);
243  }
244 
245  public String getString(Column storeColumn) {
246  int index = storeColumn.getColumnId();
247  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
248  if (ndbRecAttr.isNULL() == 1) return null;
249  int prefixLength = storeColumn.getPrefixLength();
250  int actualLength;
251  int offset = offsets[index];
252  byteBuffer.limit(byteBuffer.capacity());
253  switch (prefixLength) {
254  case 0:
255  actualLength = lengths[index];
256  break;
257  case 1:
258  actualLength = (byteBuffer.get(offset) + 256) % 256;
259  offset += 1;
260  break;
261  case 2:
262  actualLength = (byteBuffer.get(offset) + 256) % 256;
263  int length2 = (byteBuffer.get(offset + 1) + 256) % 256;
264  actualLength += 256 * length2;
265  offset += 2;
266  break;
267  default:
268  throw new ClusterJFatalInternalException(
269  local.message("ERR_Invalid_Prefix_Length", prefixLength));
270  }
271 
272  byteBuffer.position(offset);
273  byteBuffer.limit(offset + actualLength);
274 
275  String result = Utility.decode(byteBuffer, storeColumn.getCharsetNumber(), bufferManager);
276  byteBuffer.clear();
277  return result;
278  }
279 
280  public byte[] getBytes(int column) {
281  return getBytes(storeColumns[column]);
282  }
283 
284  public byte[] getBytes(Column storeColumn) {
285  int index = storeColumn.getColumnId();
286  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
287  if (ndbRecAttr.isNULL() == 1) return null;
288  int prefixLength = storeColumn.getPrefixLength();
289  int actualLength = lengths[index];
290  int offset = offsets[index];
291  switch (prefixLength) {
292  case 0:
293  break;
294  case 1:
295  actualLength = (byteBuffer.get(offset) + 256) % 256;
296  offset += 1;
297  break;
298  case 2:
299  actualLength = (byteBuffer.get(offset) + 256) % 256;
300  int length2 = (byteBuffer.get(offset + 1) + 256) % 256;
301  actualLength += 256 * length2;
302  offset += 2;
303  break;
304  default:
305  throw new ClusterJFatalInternalException(
306  local.message("ERR_Invalid_Prefix_Length", prefixLength));
307  }
308  byteBuffer.position(offset);
309  byte[] result = new byte[actualLength];
310  byteBuffer.get(result);
311  return result;
312  }
313 
314 
315  public Object getObject(int column) {
316  return getObject(storeColumns[column]);
317  }
318 
319  public Object getObject(Column storeColumn) {
320  throw new ClusterJFatalInternalException(local.message("ERR_Implementation_Should_Not_Occur"));
321  }
322 
323  public boolean wasNull(Column storeColumn) {
324  throw new ClusterJFatalInternalException(local.message("ERR_Implementation_Should_Not_Occur"));
325  }
326 
327  public Boolean getObjectBoolean(int column) {
328  return getObjectBoolean(storeColumns[column]);
329  }
330 
331  public Boolean getObjectBoolean(Column storeColumn) {
332  int index = storeColumn.getColumnId();
333  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
334  if (ndbRecAttr.isNULL() == 1) {
335  return null;
336  } else {
337  byte value = ndbRecAttr.int8_value();
338  Boolean result = (Boolean.valueOf((value & 0x01) == 0x01));
339  return result;
340  }
341  }
342 
343  public Byte getObjectByte(int column) {
344  return getObjectByte(storeColumns[column]);
345  }
346 
347  public Byte getObjectByte(Column storeColumn) {
348  int index = storeColumn.getColumnId();
349  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
350  return (ndbRecAttr.isNULL() == 1)?null:Utility.getByte(storeColumn, ndbRecAttr);
351  }
352 
353  public Short getObjectShort(int column) {
354  return getObjectShort(storeColumns[column]);
355  }
356 
357  public Short getObjectShort(Column storeColumn) {
358  int index = storeColumn.getColumnId();
359  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
360  return (ndbRecAttr.isNULL() == 1)?null:Utility.getShort(storeColumn, ndbRecAttr);
361  }
362 
363  public Integer getObjectInteger(int column) {
364  return getObjectInteger(storeColumns[column]);
365  }
366 
367  public Integer getObjectInteger(Column storeColumn) {
368  int index = storeColumn.getColumnId();
369  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
370  return (ndbRecAttr.isNULL() == 1)?null:Utility.getInt(storeColumn, ndbRecAttr);
371  }
372 
373  public Long getObjectLong(int column) {
374  return getObjectLong(storeColumns[column]);
375  }
376 
377  public Long getObjectLong(Column storeColumn) {
378  int index = storeColumn.getColumnId();
379  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
380  return (ndbRecAttr.isNULL() == 1)?null:Utility.getLong(storeColumn, ndbRecAttr);
381  }
382 
383  public Float getObjectFloat(int column) {
384  return getObjectFloat(storeColumns[column]);
385  }
386 
387  public Float getObjectFloat(Column storeColumn) {
388  int index = storeColumn.getColumnId();
389  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
390  return (ndbRecAttr.isNULL() == 1)?null:getFloat(storeColumn);
391  }
392 
393  public Double getObjectDouble(int column) {
394  return getObjectDouble(storeColumns[column]);
395  }
396 
397  public Double getObjectDouble(Column storeColumn) {
398  int index = storeColumn.getColumnId();
399  NdbRecAttr ndbRecAttr = ndbRecAttrs[index];
400  return (ndbRecAttr.isNULL() == 1)?null:getDouble(storeColumn);
401  }
402 
403  public BigInteger getBigInteger(int column) {
404  return getBigInteger(storeColumns[column]);
405  }
406 
407  public BigInteger getBigInteger(Column storeColumn) {
408  int index = storeColumn.getColumnId();
409  int offset = offsets[index];
410  int precision = storeColumn.getPrecision();
411  int scale = storeColumn.getScale();
412  int length = Utility.getDecimalColumnSpace(precision, scale);
413  byteBuffer.position(offset);
414  return Utility.getBigInteger(byteBuffer, length, precision, scale);
415  }
416 
417  public BigDecimal getDecimal(int column) {
418  return getDecimal(storeColumns[column]);
419  }
420 
421  public BigDecimal getDecimal(Column storeColumn) {
422  int index = storeColumn.getColumnId();
423  int offset = offsets[index];
424  int precision = storeColumn.getPrecision();
425  int scale = storeColumn.getScale();
426  int length = Utility.getDecimalColumnSpace(precision, scale);
427  byteBuffer.position(offset);
428  return Utility.getDecimal(byteBuffer, length, precision, scale);
429  }
430 
431  private void handleError(Object object, NdbOperation ndbOperation) {
432  if (object == null) {
433  Utility.throwError(object, ndbOperation.getNdbError());
434  }
435  }
436 
437  public void setNoResult() {
438  nextDone = true;
439  }
440 
441  public Column[] getColumns() {
442  return storeColumns;
443  }
444 
445 }