]> review.fuel-infra Code Review - packages/trusty/mysql-wsrep-5.6.git/blob
a116a287d7827c658dfec58ac8e212c061f6ca95
[packages/trusty/mysql-wsrep-5.6.git] /
1 /*
2    Copyright (c) 2010, 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.jpatest;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.nio.charset.Charset;
23 import java.nio.charset.CharsetEncoder;
24
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.List;
28
29 import com.mysql.clusterj.jpatest.model.ClobTypes;
30
31 /** Test clobs
32  * Schema:
33 drop table if exists charsetlatin1;
34 create table charsetlatin1 (
35  id int not null primary key,
36  smallcolumn varchar(200),
37  mediumcolumn varchar(500),
38  largecolumn text(10000)
39
40 ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
41  
42  */
43 public class ClobTest extends AbstractJPABaseTest {
44
45     /** The size of the clob column is 2 raised to the power i. */
46     private static final int NUMBER_TO_INSERT = 16;
47
48     /** The clob instances for testing. */
49     protected List<ClobTypes> clobs = new ArrayList<ClobTypes>();
50
51     /** Characters that can be encoded using latin1 character set */
52     private char[] chars = getChars(Charset.forName("latin1"));
53
54     /** Subclasses can override this method to get debugging info printed to System.out */
55     protected boolean getDebug() {
56         return false;
57     }
58
59     /** Create a char array with the first 128 encodable characters.
60      * 
61      * @return the char array
62      */
63     private char[] getChars(Charset charset) {
64         CharsetEncoder encoder = charset.newEncoder();
65         char[] result = new char[128];
66         char current = (char)0;
67         for (int i = 0; i < result.length; ++i) {
68             current = nextChar(encoder, current);
69             result[i] = current;
70         }
71         return result;
72     }
73
74     /** Get the next char greater than the current char that is encodable
75      * by the encoder.
76      * @param encoder 
77      * 
78      */
79     char nextChar(CharsetEncoder encoder, char current) {
80         current++;
81         if (encoder.canEncode(current)) {
82             return current;
83         } else {
84             return nextChar(encoder, current);
85         }
86     }
87
88     public void test() {
89         createClobInstances(NUMBER_TO_INSERT);
90         remove();
91         insert();
92         update();
93         failOnError();
94     }
95
96     protected void remove() {
97         removeAll(ClobTypes.class);
98     }
99
100     protected void insert() {
101         // insert instances
102         tx = em.getTransaction();
103         tx.begin();
104         
105         int count = 0;
106
107         for (int i = 0; i < NUMBER_TO_INSERT; ++i) {
108             // must be done with an active transaction
109             em.persist(clobs.get(i));
110             ++count;
111         }
112         tx.commit();
113     }
114
115     protected void update() {
116
117         tx.begin();
118
119         for (int i = 1; i < NUMBER_TO_INSERT; ++i) {
120             // must be done with an active transaction
121             ClobTypes e = em.find(ClobTypes.class, i);
122             // see if it is the right one
123             int actualId = e.getId();
124             if (actualId != i) {
125                 error("Expected ClobTypes.id " + i + " but got " + actualId);
126             }
127             String string = e.getLarge10000();
128             // make sure all fields were fetched properly
129             checkString("before update", string, i, false);
130
131             int position = getClobSizeFor(i)/2;
132             // only update if the length is correct
133             if (string.length() == (position * 2)) {
134                 StringBuilder sb = new StringBuilder(string);
135                 // modify the byte in the middle of the blob
136                 sb.replace(position, position + 1, "!");
137                 string = sb.toString();
138                 checkString("after update", string, i, true);
139             }
140             e.setLarge10000(string);
141         }
142         tx.commit();
143         tx.begin();
144
145         for (int i = 1; i < NUMBER_TO_INSERT; ++i) {
146             // must be done with an active transaction
147             ClobTypes e = em.find(ClobTypes.class, i);
148             // see if it is the right one
149             int actualId = e.getId();
150             if (actualId != i) {
151                 error("Expected ClobTypes.id " + i + " but got " + actualId);
152             }
153             String string = e.getLarge10000();
154
155             // check to see that the blob field has the right data
156             checkString("after commit", string, i, true);
157         }
158         tx.commit();
159     }
160
161     protected void createClobInstances(int number) {
162         for (int i = 0; i < number; ++i) {
163             ClobTypes instance = new ClobTypes();
164             instance.setId(i);
165             int length = getClobSizeFor(i);
166             instance.setLarge10000(getString(length));
167 //            blob streams are not yet supported
168 //            instance.setBlobstream(getBlobStream(length));
169             clobs.add(instance);
170         }
171     }
172
173     /** Create a new String of the specified size containing a pattern
174      * of characters in which each character is the value of encodable characters
175      * at position modulo 128. This pattern is easy to test.
176      * @param size the length of the returned string
177      * @return the string filled with the pattern
178      */
179     protected String getString(int size) {
180         char[] result = new char[size];
181         for (int i = 0; i < size; ++i) {
182             result[i] = chars [i%128];
183         }
184         return new String(result);
185     }
186
187     /** Check the string to be sure it matches the pattern in both size
188      * and contents.
189      * @see getString
190      * @param string the string to check
191      * @param number the expected length of the string
192      * @param updated whether the string is original or updated
193      */
194     protected void checkString(String where, String string, int number, boolean updated) {
195         if (getDebug()) dumpClob(where, string);
196         int expectedSize = getClobSizeFor(number);
197         int actualSize = string.length();
198         if (expectedSize != actualSize) {
199             error("In " + where
200                     + " wrong size of string; "
201                     + "expected: " + expectedSize
202                     + " actual: " + actualSize);
203         }
204         for (int i = 0; i < actualSize; ++i) {
205             char expected;
206             int position = expectedSize/2;
207             if (updated && (i == position)) {
208                 expected = '!';
209             } else {
210                 expected = chars[i%128];
211             }
212                 char actual = string.charAt(i);
213             if (expected != actual) {
214                 error("In " + where + " for size: " + actualSize
215                         + " mismatch in string at position " + i
216                         + " expected: " + (int)expected
217                         + " actual: " + (int)actual);
218             }
219         }
220
221     }
222
223     protected InputStream getClobStream(final int i) {
224         return new InputStream() {
225             int size = i;
226             int counter = 0;
227             @Override
228             public int read() throws IOException {
229                 if (counter >= i) {
230                     return -1;
231                 } else {
232                     return counter++ %256;
233                 }
234             }
235         };
236     }
237
238     protected void dumpClob(String where, String string) {
239         System.out.println("In " + where + " dumpClob of size: " + string.length() + " " + Arrays.toString(string.getBytes()));
240     }
241
242     protected int getClobSizeFor(int i) {
243         int length = (int) Math.pow(2, i);
244         return length;
245     }
246
247 }