]> review.fuel-infra Code Review - packages/trusty/mysql-wsrep-5.6.git/blob
6d8e62361a203586f029062bffe22270d31edfb9
[packages/trusty/mysql-wsrep-5.6.git] /
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
44 /**
45  *
46  */
47 class ResultDataImpl implements ResultData {
48
49     /** My message translator */
50     static final I18NHelper local = I18NHelper
51             .getInstance(ResultDataImpl.class);
52
53     /** My logger */
54     static final Logger logger = LoggerFactoryService.getFactory()
55             .getInstance(ResultDataImpl.class);
56
57     /** Flags for iterating a scan */
58     protected final int RESULT_READY = 0;
59     protected final int SCAN_FINISHED = 1;
60     protected final int CACHE_EMPTY = 2;
61
62     /** The NdbOperation that defines the result */
63     private NdbOperation ndbOperation = null;
64
65     /** The NdbRecAttrs that specify the columns to retrieve */
66     private NdbRecAttr[] ndbRecAttrs = null;
67
68     /** The flag indicating that there are no more results */
69     private boolean nextDone;
70
71     /** The ByteBuffer containing the results, possibly obtained from buffer manager */
72     private ByteBuffer byteBuffer = null;
73
74     /** Offsets into the ByteBuffer containing the results */
75     private int[] offsets = null;
76
77     /** Lengths of the fields in the ByteBuffer containing the results */
78     private int[] lengths = null;
79
80     /** The Columns in this result */
81     private final Column[] storeColumns;
82
83     /** The buffer manager */
84     private BufferManager bufferManager;
85
86     /** Construct the ResultDataImpl based on an NdbOperation, a list of columns
87      * to include in the result, and the pre-computed buffer layout for the result.
88      * @param ndbOperation the NdbOperation
89      * @param storeColumns the columns in the result
90      * @param maximumColumnId the largest column id
91      * @param bufferSize the size of the buffer needed
92      * @param offsets the array of offsets indexed by column id
93      * @param lengths the array of lengths indexed by column id
94      * @param bufferManager the buffer manager
95      * @param allocateNew true to allocate a new (unshared) result buffer
96      */
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 }