1 /*
2  *  Copyright (c) 2010, 2021, Oracle and/or its affiliates.
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, version 2.0,
6  *  as published by the Free Software Foundation.
7  *
8  *  This program is also distributed with certain software (including
9  *  but not limited to OpenSSL) that is licensed under separate terms,
10  *  as designated in a particular file or component or in included license
11  *  documentation.  The authors of MySQL hereby grant you an additional
12  *  permission to link the program and your derivative works with the
13  *  separately licensed software that they have included with MySQL.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License, version 2.0, for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23  */
24 
25 package com.mysql.clusterj.tie;
26 
27 import java.math.BigDecimal;
28 import java.math.BigInteger;
29 import java.nio.ByteBuffer;
30 import java.util.Arrays;
31 
32 import com.mysql.ndbjtie.ndbapi.NdbScanFilter;
33 
34 import com.mysql.clusterj.ClusterJFatalInternalException;
35 
36 import com.mysql.clusterj.core.store.Column;
37 import com.mysql.clusterj.core.store.ScanFilter;
38 import com.mysql.clusterj.core.util.I18NHelper;
39 import com.mysql.clusterj.core.util.Logger;
40 import com.mysql.clusterj.core.util.LoggerFactoryService;
41 
42 /**
43  *
44  */
45 class ScanFilterImpl implements ScanFilter {
46 
47     /** My message translator */
48     static final I18NHelper local = I18NHelper
49             .getInstance(ScanFilterImpl.class);
50 
51     /** My logger */
52     static final Logger logger = LoggerFactoryService.getFactory()
53             .getInstance(ScanFilterImpl.class);
54 
55     private NdbScanFilter ndbScanFilter;
56 
ScanFilterImpl(NdbScanFilter ndbScanFilter)57     public ScanFilterImpl(NdbScanFilter ndbScanFilter) {
58         this.ndbScanFilter = ndbScanFilter;
59     }
60 
begin()61     public void begin() {
62         int returnCode = ndbScanFilter.begin(NdbScanFilter.Group.AND);
63         handleError(returnCode, ndbScanFilter);
64     }
65 
begin(Group group)66     public void begin(Group group) {
67         int returnCode = ndbScanFilter.begin(convertGroup(group));
68         handleError(returnCode, ndbScanFilter);
69     }
70 
cmpBigInteger(BinaryCondition condition, Column storeColumn, BigInteger value)71     public void cmpBigInteger(BinaryCondition condition, Column storeColumn, BigInteger value) {
72         ByteBuffer buffer = Utility.convertValue(storeColumn, value);
73         int returnCode = ndbScanFilter.cmp(convertCondition(condition),
74                 storeColumn.getColumnId(), buffer, buffer.capacity());
75         handleError(returnCode, ndbScanFilter);
76     }
77 
cmpBoolean(BinaryCondition condition, Column storeColumn, boolean value)78     public void cmpBoolean(BinaryCondition condition, Column storeColumn, boolean value) {
79         byte byteValue = (value?(byte)0x01:(byte)0x00);
80         cmpByte(condition, storeColumn, byteValue);
81     }
82 
cmpByte(BinaryCondition condition, Column storeColumn, byte value)83     public void cmpByte(BinaryCondition condition, Column storeColumn, byte value) {
84         ByteBuffer buffer = Utility.convertValue(storeColumn, value);
85         int returnCode = ndbScanFilter.cmp(convertCondition(condition),
86                 storeColumn.getColumnId(), buffer, buffer.capacity());
87         handleError(returnCode, ndbScanFilter);
88     }
89 
cmpBytes(BinaryCondition condition, Column storeColumn, byte[] value)90     public void cmpBytes(BinaryCondition condition, Column storeColumn, byte[] value) {
91         ByteBuffer buffer;
92         if (condition == BinaryCondition.COND_LIKE) {
93             buffer = Utility.convertValueForLikeFilter(storeColumn, value);
94         } else {
95             buffer = Utility.convertValue(storeColumn, value);
96         }
97         int returnCode = ndbScanFilter.cmp(convertCondition(condition),
98                 storeColumn.getColumnId(), buffer, buffer.capacity());
99         handleError(returnCode, ndbScanFilter);
100     }
101 
cmpDecimal(BinaryCondition condition, Column storeColumn, BigDecimal value)102     public void cmpDecimal(BinaryCondition condition, Column storeColumn, BigDecimal value) {
103         ByteBuffer buffer = Utility.convertValue(storeColumn, value);
104         int returnCode = ndbScanFilter.cmp(convertCondition(condition),
105                 storeColumn.getColumnId(), buffer, buffer.capacity());
106         handleError(returnCode, ndbScanFilter);
107     }
108 
cmpDouble(BinaryCondition condition, Column storeColumn, double value)109     public void cmpDouble(BinaryCondition condition, Column storeColumn, double value) {
110         ByteBuffer buffer = Utility.convertValue(storeColumn, value);
111         int returnCode = ndbScanFilter.cmp(convertCondition(condition),
112                 storeColumn.getColumnId(), buffer, buffer.capacity());
113         handleError(returnCode, ndbScanFilter);
114     }
115 
cmpFloat(BinaryCondition condition, Column storeColumn, float value)116     public void cmpFloat(BinaryCondition condition, Column storeColumn, float value) {
117         ByteBuffer buffer = Utility.convertValue(storeColumn, value);
118         int returnCode = ndbScanFilter.cmp(convertCondition(condition),
119                 storeColumn.getColumnId(), buffer, buffer.capacity());
120         handleError(returnCode, ndbScanFilter);
121     }
122 
cmpShort(BinaryCondition condition, Column storeColumn, short value)123     public void cmpShort(BinaryCondition condition, Column storeColumn, short value) {
124         ByteBuffer buffer = Utility.convertValue(storeColumn, value);
125         int returnCode = ndbScanFilter.cmp(convertCondition(condition),
126                 storeColumn.getColumnId(), buffer, buffer.capacity());
127         handleError(returnCode, ndbScanFilter);
128     }
129 
cmpInt(BinaryCondition condition, Column storeColumn, int value)130     public void cmpInt(BinaryCondition condition, Column storeColumn, int value) {
131         ByteBuffer buffer = Utility.convertValue(storeColumn, value);
132         int returnCode = ndbScanFilter.cmp(convertCondition(condition),
133                 storeColumn.getColumnId(), buffer, buffer.capacity());
134         handleError(returnCode, ndbScanFilter);
135     }
136 
cmpLong(BinaryCondition condition, Column storeColumn, long value)137     public void cmpLong(BinaryCondition condition, Column storeColumn, long value) {
138         ByteBuffer buffer = Utility.convertValue(storeColumn, value);
139         if (logger.isDetailEnabled()) {
140             int bufferLength = buffer.limit() - buffer.position();
141             byte[] array = new byte[bufferLength];
142             buffer.get(array);
143             buffer.flip();
144             logger.detail("column: " + storeColumn.getName() + " condition: " + condition.toString() + " value: " + value + Arrays.toString(array) + "(" + buffer.capacity() + ")");
145         }
146         int returnCode = ndbScanFilter.cmp(convertCondition(condition),
147                 storeColumn.getColumnId(), buffer, buffer.capacity());
148         handleError(returnCode, ndbScanFilter);
149     }
150 
cmpString(BinaryCondition condition, Column storeColumn, String value)151     public void cmpString(BinaryCondition condition, Column storeColumn, String value) {
152         if (logger.isDebugEnabled())
153             logger.debug(storeColumn.getName() + " " + condition + " " + value);
154         ByteBuffer buffer;
155         if (condition == BinaryCondition.COND_LIKE) {
156             buffer = Utility.convertValueForLikeFilter(storeColumn, value);
157         } else {
158             buffer = Utility.convertValue(storeColumn, value);
159         }
160         int returnCode = ndbScanFilter.cmp(convertCondition(condition),
161                 storeColumn.getColumnId(), buffer, buffer.limit());
162         handleError(returnCode, ndbScanFilter);
163     }
164 
isNull(Column storeColumn)165     public void isNull(Column storeColumn) {
166         int returnCode = ndbScanFilter.isnull(storeColumn.getColumnId());
167         handleError(returnCode, ndbScanFilter);
168     }
169 
isNotNull(Column storeColumn)170     public void isNotNull(Column storeColumn) {
171         int returnCode = ndbScanFilter.isnotnull(storeColumn.getColumnId());
172         handleError(returnCode, ndbScanFilter);
173     }
174 
end()175     public void end() {
176         int returnCode = ndbScanFilter.end();
177         handleError(returnCode, ndbScanFilter);
178     }
179 
convertCondition(BinaryCondition condition)180     private int convertCondition(BinaryCondition condition) {
181         switch (condition) {
182             case COND_EQ:
183                 return NdbScanFilter.BinaryCondition.COND_EQ;
184             case COND_LE:
185                 return NdbScanFilter.BinaryCondition.COND_LE;
186             case COND_LT:
187                 return NdbScanFilter.BinaryCondition.COND_LT;
188             case COND_GE:
189                 return NdbScanFilter.BinaryCondition.COND_GE;
190             case COND_GT:
191                 return NdbScanFilter.BinaryCondition.COND_GT;
192             case COND_LIKE:
193                 return NdbScanFilter.BinaryCondition.COND_LIKE;
194             default:
195                 throw new ClusterJFatalInternalException(
196                         local.message("ERR_Implementation_Should_Not_Occur"));
197         }
198     }
199 
convertGroup(Group group)200     private int convertGroup(Group group) {
201         switch(group) {
202             case GROUP_AND:
203                 return NdbScanFilter.Group.AND;
204             case GROUP_NAND:
205                 return NdbScanFilter.Group.NAND;
206             case GROUP_OR:
207                 return NdbScanFilter.Group.OR;
208             default:
209                 throw new ClusterJFatalInternalException(
210                         local.message("ERR_Implementation_Should_Not_Occur"));
211         }
212     }
213 
handleError(int returnCode, NdbScanFilter ndbScanFilter)214     protected static void handleError(int returnCode, NdbScanFilter ndbScanFilter) {
215         if (returnCode == 0) {
216             return;
217         } else {
218             Utility.throwError(returnCode, ndbScanFilter.getNdbError());
219         }
220     }
221 
handleError(Object object, NdbScanFilter ndbScanFilter)222     protected static void handleError(Object object, NdbScanFilter ndbScanFilter) {
223         if (object != null) {
224             return;
225         } else {
226             Utility.throwError(null, ndbScanFilter.getNdbError());
227         }
228     }
229 
delete()230     public void delete() {
231         NdbScanFilter.delete(ndbScanFilter);
232     }
233 
234 }
235