1 /*
2  *  Copyright (c) 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, 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 jdbctest;
26 
27 import java.math.BigDecimal;
28 import java.sql.PreparedStatement;
29 import java.sql.SQLException;
30 import java.util.Properties;
31 
32 public class UpdateDecimalTypesTest extends testsuite.clusterj.DecimalTypesTest {
33 
34     /** Test all DecimalTypes columns.
35 drop table if exists decimaltypes;
36 create table decimaltypes (
37  id int not null primary key,
38 
39  decimal_null_hash decimal(10,5),
40  decimal_null_btree decimal(10,5),
41  decimal_null_both decimal(10,5),
42  decimal_null_none decimal(10,5)
43 
44 ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
45 
46 create unique index idx_decimal_null_hash using hash on decimaltypes(decimal_null_hash);
47 create index idx_decimal_null_btree on decimaltypes(decimal_null_btree);
48 create unique index idx_decimal_null_both on decimaltypes(decimal_null_both);
49 
50      */
51 
52     /** One of two tests in the superclass that we don't want to run */
53     @Override
testWriteJDBCReadNDB()54     public void testWriteJDBCReadNDB() {
55     }
56 
57     /** One of two tests in the superclass that we don't want to run */
58     @Override
testWriteNDBReadJDBC()59     public void testWriteNDBReadJDBC() {
60    }
61 
62     @Override
getNumberOfInstances()63     protected int getNumberOfInstances() {
64         return 5;
65     }
66 
67     @Override
localSetUp()68     public void localSetUp() {
69         createSessionFactory();
70         session = sessionFactory.getSession();
71         setAutoCommit(connection, false);
72         if (getModelClass() != null && getCleanupAfterTest()) {
73             addTearDownClasses(getModelClass());
74         }
75     }
76 
77     @Override
getCleanupAfterTest()78     protected boolean getCleanupAfterTest() {
79         return true;
80     }
81 
testAllVariants()82     public void testAllVariants() {
83         // initialization is the same for all variants
84         generateInstances(getColumnDescriptors());
85         writeToJDBC(columnDescriptors, instances);
86         // test all variants of server-prepared statement and rewrite-batch
87         rewrite_server();
88         rewrite_server_autocommit();
89         rewrite();
90         rewrite_autocommit();
91         server();
92         server_autocommit();
93         none();
94         none_autocommit();
95         failOnError();
96     }
97 
rewrite_server()98     public void rewrite_server() {
99         Properties extraProperties = new Properties();
100         extraProperties.put("rewriteBatchedStatements", "true");
101         extraProperties.put("useServerPrepStmts", "true");
102         extraProperties.put("cachePrepStmts", "true");
103         updateAndCheck(extraProperties, 5, false, "rewrite_server");
104     }
105 
rewrite_server_autocommit()106     public void rewrite_server_autocommit() {
107         Properties extraProperties = new Properties();
108         extraProperties.put("rewriteBatchedStatements", "true");
109         extraProperties.put("useServerPrepStmts", "true");
110         extraProperties.put("cachePrepStmts", "true");
111         updateAndCheck(extraProperties, 5, true, "rewrite_server");
112     }
113 
rewrite()114     public void rewrite() {
115         Properties extraProperties = new Properties();
116         extraProperties.put("rewriteBatchedStatements", "true");
117         extraProperties.put("useServerPrepStmts", "false");
118         extraProperties.put("cachePrepStmts", "true");
119         updateAndCheck(extraProperties, 4, false, "rewrite");
120     }
121 
rewrite_autocommit()122     public void rewrite_autocommit() {
123         Properties extraProperties = new Properties();
124         extraProperties.put("rewriteBatchedStatements", "true");
125         extraProperties.put("useServerPrepStmts", "false");
126         extraProperties.put("cachePrepStmts", "true");
127         updateAndCheck(extraProperties, 4, true, "rewrite");
128     }
129 
server()130     public void server() {
131         Properties extraProperties = new Properties();
132         extraProperties.put("rewriteBatchedStatements", "false");
133         extraProperties.put("useServerPrepStmts", "true");
134         extraProperties.put("cachePrepStmts", "true");
135         updateAndCheck(extraProperties, 3, false, "server");
136     }
137 
server_autocommit()138     public void server_autocommit() {
139         Properties extraProperties = new Properties();
140         extraProperties.put("rewriteBatchedStatements", "false");
141         extraProperties.put("useServerPrepStmts", "true");
142         extraProperties.put("cachePrepStmts", "true");
143         updateAndCheck(extraProperties, 3, true, "server");
144     }
145 
none()146     public void none() {
147         Properties extraProperties = new Properties();
148         extraProperties.put("rewriteBatchedStatements", "false");
149         extraProperties.put("useServerPrepStmts", "false");
150         extraProperties.put("cachePrepStmts", "true");
151         updateAndCheck(extraProperties, 2, false, "none");
152     }
153 
none_autocommit()154     public void none_autocommit() {
155         Properties extraProperties = new Properties();
156         extraProperties.put("rewriteBatchedStatements", "false");
157         extraProperties.put("useServerPrepStmts", "false");
158         extraProperties.put("cachePrepStmts", "true");
159         updateAndCheck(extraProperties, 2, true, "none");
160     }
161 
updateAndCheck(Properties extraProperties, int updateMultiplier, boolean autocommit, String where)162     private void updateAndCheck(Properties extraProperties, int updateMultiplier, boolean autocommit, String where) {
163         // close the existing connection (it has the wrong connection properties)
164         closeConnection();
165         getConnection(extraProperties);
166         updateByPrimaryKey(updateMultiplier, autocommit, where);
167         updateByUniqueKey(updateMultiplier, autocommit, where);
168     }
169 
170     /** Update by primary key */
updateByPrimaryKey(int multiplier, boolean autocommit, String where)171     public void updateByPrimaryKey(int multiplier, boolean autocommit, String where) {
172         // the expected results are e.g. [1, 1, 1, 1, 0] for number of instances 4
173         // the last update is for a row that does not exist (one more than the number of rows in the table)
174         int[] expected = new int[instances.size() + 1];
175         for (int i = 0; i < getNumberOfInstances(); ++i) {
176             expected[i] = 1;
177         }
178         try {
179             connection.setAutoCommit(autocommit);
180             PreparedStatement preparedStatement = connection.prepareStatement("UPDATE decimaltypes SET " +
181                     "decimal_null_hash = ?, " +
182                     "decimal_null_both = ?, " +
183                     "decimal_null_none = ?, " +
184                     "decimal_null_btree = ? " +
185                     "WHERE id = ?");
186             for (int i = 0; i < instances.size() + 1; ++i) {
187                 preparedStatement.setBigDecimal(1, new BigDecimal(i * multiplier));
188                 preparedStatement.setBigDecimal(2, new BigDecimal(2 * i * multiplier));
189                 preparedStatement.setBigDecimal(3, new BigDecimal(3 * i * multiplier));
190                 preparedStatement.setBigDecimal(4, new BigDecimal(4 * i * multiplier));
191                 preparedStatement.setInt(5, i);
192                 preparedStatement.addBatch();
193             }
194             int[] actual = preparedStatement.executeBatch();
195             errorIfNotEqual("Results of executeBatch for update {server, rewrite}: " + where, expected, actual);
196             queryAndVerifyResults("decimal_null_btree equal", columnDescriptors,
197                     "decimal_null_btree = ?", new BigDecimal[] {BigDecimal.valueOf(4 * multiplier)}, 1);
198         } catch (SQLException e) {
199             error(e.getMessage());
200             // TODO Auto-generated catch block
201             e.printStackTrace();
202         }
203     }
204 
205     /** Update by unique key */
updateByUniqueKey(int multiplier, boolean autocommit, String where)206     public void updateByUniqueKey(int multiplier, boolean autocommit, String where) {
207         // the expected results are e.g. [1, 1, 1, 1, 0] for number of instances 4
208         // the last update is for a row that does not exist (one more than the number of rows in the table)
209         int[] expected = new int[instances.size() + 1];
210         for (int i = 0; i < getNumberOfInstances(); ++i) {
211             expected[i] = 1;
212         }
213         try {
214             connection.setAutoCommit(autocommit);
215             PreparedStatement preparedStatement = connection.prepareStatement("UPDATE decimaltypes SET " +
216                     "decimal_null_both = ?, " +
217                     "decimal_null_none = ?, " +
218                     "decimal_null_btree = ? " +
219                     "WHERE decimal_null_hash = ?");
220             for (int i = 0; i < instances.size() + 1; ++i) {
221                 preparedStatement.setBigDecimal(1, new BigDecimal(2 * i * multiplier * 20));
222                 preparedStatement.setBigDecimal(2, new BigDecimal(3 * i * multiplier * 20));
223                 preparedStatement.setBigDecimal(3, new BigDecimal(4 * i * multiplier * 20));
224                 preparedStatement.setBigDecimal(4, new BigDecimal(i * multiplier));
225                 preparedStatement.addBatch();
226             }
227             int[] actual = preparedStatement.executeBatch();
228             errorIfNotEqual("Results of executeBatch for update {server, rewrite}: " + where, expected, actual);
229             queryAndVerifyResults("decimal_null_btree equal", columnDescriptors,
230                     "decimal_null_btree = ?", new BigDecimal[] {BigDecimal.valueOf(4 * multiplier * 20)}, 1);
231         } catch (SQLException e) {
232             error(e.getMessage());
233             // TODO Auto-generated catch block
234             e.printStackTrace();
235         }
236     }
237 
238 }
239