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