18 package testsuite.clusterj;
20 import java.lang.reflect.InvocationHandler;
21 import java.lang.reflect.Method;
22 import java.lang.reflect.Proxy;
23 import java.sql.Connection;
24 import java.sql.PreparedStatement;
25 import java.sql.ResultSet;
26 import java.sql.SQLException;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Calendar;
30 import java.util.Comparator;
31 import java.util.HashMap;
32 import java.util.List;
35 import java.util.TimeZone;
36 import java.util.TreeSet;
38 import com.mysql.clusterj.Session;
40 import testsuite.clusterj.model.AllPrimitives;
41 import testsuite.clusterj.model.Dn2id;
42 import testsuite.clusterj.model.Employee;
43 import testsuite.clusterj.model.IdBase;
57 protected static final long ONE_HOUR = 1000L * 60L * 60L;
60 protected static final long TEN_HOURS = 1000L * 60L * 60L * 10L;
63 protected static final long ONE_DAY = 1000L * 60L * 60L * 24L;
74 protected static long getMillisFor(
int year,
int month,
int day,
int hour,
int minute,
int second) {
75 Calendar calendar = Calendar.getInstance();
77 calendar.set(Calendar.YEAR, year);
78 calendar.set(Calendar.MONTH, month);
79 calendar.set(Calendar.DATE, day);
80 calendar.set(Calendar.HOUR, hour);
81 calendar.set(Calendar.MINUTE, minute);
82 calendar.set(Calendar.SECOND, second);
83 calendar.set(Calendar.MILLISECOND, 0);
84 long result = calendar.getTimeInMillis();
96 Calendar calendar = Calendar.getInstance();
98 calendar.set(Calendar.YEAR, year);
99 calendar.set(Calendar.MONTH, month);
100 calendar.set(Calendar.DATE, day);
101 calendar.set(Calendar.HOUR, 0);
102 calendar.set(Calendar.MINUTE, 0);
103 calendar.set(Calendar.SECOND, 0);
104 calendar.set(Calendar.MILLISECOND, 0);
105 long result = calendar.getTimeInMillis();
118 protected static long getMillisFor(
int days,
int hour,
int minute,
int second) {
119 Calendar calendar = Calendar.getInstance();
121 calendar.set(Calendar.DATE, days + 1);
122 calendar.set(Calendar.HOUR, hour);
123 calendar.set(Calendar.MINUTE, minute);
124 calendar.set(Calendar.SECOND, second);
125 calendar.set(Calendar.MILLISECOND, 0);
126 long result = calendar.getTimeInMillis();
131 String[] a1values =
new String[]{
"dc=abc",
"dc=prs",
"dc=xyz"};
137 protected static Object[] dn2idPK = setupDn2idPK();
140 protected List<IdBase>
instances =
new ArrayList<IdBase>();
143 private List<Object[]> expected = null;
146 ColumnDescriptor[] columnDescriptors = null;
155 protected boolean getCleanupAfterTest() {
161 createSessionFactory();
163 setAutoCommit(connection,
false);
164 if (getModelClass() != null && getCleanupAfterTest()) {
165 addTearDownClasses(getModelClass());
177 PreparedStatement
statement = connection.prepareStatement(
"select @@global.time_zone, @@global.system_time_zone, @@session.time_zone");
178 ResultSet rs = statement.executeQuery();
181 String globalTimeZone = rs.getString(1);
182 String globalSystemTimeZone = rs.getString(2);
183 String sessionTimeZone = rs.getString(3);
187 if (
"SYSTEM".equalsIgnoreCase(globalTimeZone)) {
188 globalTimeZone = globalSystemTimeZone;
190 globalTimeZone =
"GMT" + globalTimeZone;
198 }
catch (SQLException e) {
199 throw new RuntimeException(
"setServerTimeZone failed", e);
203 protected void setAutoCommit(Connection connection,
boolean b) {
205 connection.setAutoCommit(
false);
206 }
catch (SQLException e) {
207 throw new RuntimeException(
"setAutoCommit failed", e);
211 protected void createEmployeeInstances(
int count) {
212 employees =
new ArrayList<Employee>(count);
213 for (
int i = 0;
i < count; ++
i) {
216 emp.setName(
"Employee number " +
i);
223 protected void consistencyCheck(
Employee emp) {
224 int id = emp.getId();
225 String expectedName =
"Employee number " +
id;
226 String actualName = emp.getName();
227 if (!expectedName.equals(actualName)) {
230 error(
"Employee " +
id
231 +
" name mismatch; expected length: " + expectedName.length() +
"'" + expectedName
232 +
"'; actual length: " + actualName.length() +
"'" + actualName +
"'");
234 int actualAge = emp.getAge();
235 if (!(actualAge ==
id)) {
236 error(
"Employee " +
id
237 +
" age mismatch; expected " +
id
238 +
"'; actual '" + actualAge);
240 int actualMagic = emp.getMagic();
241 if (!(actualMagic ==
id)) {
242 error(
"Employee " +
id
243 +
" magic mismatch; expected " +
id
244 +
"'; actual '" + actualMagic);
248 protected <T>
void consistencyCheck(Iterable<T>
instances) {
249 for (T instance: instances) {
251 consistencyCheck((Employee)instance);
252 }
else if (instance instanceof Dn2id) {
253 consistencyCheck((Dn2id)instance);
258 protected void createDn2idInstances(
int number) {
259 dn2ids =
new ArrayList<Dn2id>();
260 for (
int i = 0;
i < number; ++
i) {
263 d.setObjectClasses(
"testObject");
267 d.setA1(getA1for(number,
i));
268 d.setA2(
"ou=people");
269 d.setA3(getA3for(
i));
286 protected void consistencyCheck(Dn2id dn2id) {
287 long eid = dn2id.getEid();
288 String expected = getA3for(eid);
289 String actual = dn2id.getA3();
290 if (!expected.equals(actual)) {
292 +
" a3 mismatch; expected '" + expected
293 +
"'; actual '" + actual +
"'");
318 Class<? extends IdBase> getModelClass() {
330 removeAll(getModelClass());
331 List<Object[]> result = null;
340 removeAll(getModelClass());
341 List<Object[]> result = null;
350 removeAll(getModelClass());
351 List<Object[]> result = null;
360 removeAll(getModelClass());
361 List<Object[]> result = null;
368 private String dumpListOfObjectArray(List<Object[]> results) {
370 for (Object[] row: results) {
371 result.append(
"Id: ");
372 for (Object column: row) {
373 result.append(column);
378 return result.toString();
381 protected void queryAndVerifyResults(
String where, ColumnDescriptor[] columnDescriptors,
382 String conditions, Object[] parameters,
int... objectIds) {
384 verifyQueryResults(where, results, objectIds);
388 protected List<Object[]>
queryJDBC(ColumnDescriptor[] columnDescriptors,
389 String conditions, Object[] parameters) {
392 List<Object[]> result =
new ArrayList<Object[]>();
394 for (ColumnDescriptor columnDescriptor: columnDescriptors) {
396 buffer.append(columnDescriptor.getColumnName());
398 buffer.append(
" FROM ");
399 buffer.append(tableName);
400 buffer.append(
" WHERE ");
401 buffer.append(conditions);
403 if (debug) System.out.println(statement);
404 PreparedStatement preparedStatement = null;
407 preparedStatement = connection.prepareStatement(statement);
408 for (Object parameter: parameters) {
409 preparedStatement.setObject(p++, parameter);
411 ResultSet rs = preparedStatement.executeQuery();
413 Object[] row =
new Object[columnDescriptors.length + 1];
415 row[0] = rs.getInt(1);
416 for (ColumnDescriptor columnDescriptor: columnDescriptors) {
417 row[j] = columnDescriptor.getResultSetValue(rs, j + 1);
423 }
catch (SQLException e) {
424 throw new RuntimeException(
"Failed to read " + tableName, e);
426 if (debug) System.out.println(
"readFromJDBC: " + dumpObjectArray(result));
431 private String dumpObjectArray(List<Object[]> results) {
433 for (Object[] row: results) {
434 result.append(
"Id: ");
435 for (Object column: row) {
436 result.append(column);
441 return result.toString();
444 protected void verifyQueryResults(
String where,
List<Object[]> results,
int... objectIds) {
445 errorIfNotEqual(where +
" mismatch in number of results.", objectIds.length, results.size());
446 for (Object[] result: results) {
447 int id = (Integer)result[0];
448 if (Arrays.binarySearch(objectIds,
id) < 0) {
450 error(where +
" result " +
id +
" not expected.");
461 protected void verify(
String where, List<Object[]> expecteds, List<Object[]> actuals) {
462 if (expecteds.size() != actuals.size()) {
463 error(where +
" failure on size of results: expected: " + expecteds.size() +
" actual: " + actuals.size());
466 for (
int i = 0;
i < expecteds.size(); ++
i) {
467 Object[] expected = expecteds.get(
i);
468 Object[] actual = actuals.get(
i);
469 errorIfNotEqual(where +
" got failure on id for row " +
i,
i, actual[0]);
470 for (
int j = 1; j < expected.length; ++j) {
471 errorIfNotEqual(where +
" got failure to match column data for row "
472 +
i +
" column " + j,
473 expected[j], actual[j]);
484 Class<? extends IdBase> modelClass = getModelClass();
485 expected =
new ArrayList<Object[]>();
486 instances =
new ArrayList<IdBase>();
489 for (
int i = 0;
i < numberOfInstances; ++
i) {
495 for (ColumnDescriptor columnDescriptor: columnDescriptors) {
498 columnDescriptor.setFieldValue(instance, value);
500 if (debug) System.out.println(
"generateInstances set field " + columnDescriptor.getColumnName() +
" to value " + value);
503 instances.add(instance);
504 Object[] expectedRow = createRow(columnDescriptors, instance);
505 expected.add(expectedRow);
507 if (debug) System.out.println(
"Created " + instances.size() +
" instances of " + modelClass.getName());
521 protected void writeToJDBC(ColumnDescriptor[] columnDescriptors, List<IdBase> instances) {
524 buffer.append(tableName);
525 buffer.append(
" (id");
526 for (ColumnDescriptor columnDescriptor: columnDescriptors) {
528 buffer.append(columnDescriptor.getColumnName());
530 buffer.append(
") VALUES (?");
531 for (ColumnDescriptor columnDescriptor: columnDescriptors) {
532 buffer.append(
", ?");
536 if (debug) System.out.println(statement);
538 PreparedStatement preparedStatement = null;
541 preparedStatement = connection.prepareStatement(statement);
542 if (debug) System.out.println(preparedStatement.toString());
543 for (i = 0; i < instances.size(); ++
i) {
544 IdBase instance = instances.get(i);
545 preparedStatement.setInt(1, instance.getId());
547 for (ColumnDescriptor columnDescriptor: columnDescriptors) {
548 Object value = columnDescriptor.getFieldValue(instance);
549 columnDescriptor.setPreparedStatementValue(preparedStatement, j++, value);
550 if (debug) System.out.println(
"writeToJDBC set column: " + columnDescriptor.getColumnName() +
" to value: " + value);
552 preparedStatement.execute();
555 }
catch (SQLException e) {
556 throw new RuntimeException(
"Failed to insert " + tableName +
" at instance " + i, e);
561 protected void writeToNDB(ColumnDescriptor[] columnDescriptors, List<IdBase> instances) {
568 protected List<Object[]>
readFromNDB(ColumnDescriptor[] columnDescriptors) {
569 Class<? extends IdBase> modelClass = getModelClass();
570 List<Object[]> result =
new ArrayList<Object[]>();
574 if (instance != null) {
575 Object[] row = createRow(columnDescriptors, instance);
580 if (debug) System.out.println(
"readFromNDB: " + dumpListOfObjectArray(result));
589 private Object[] createRow(ColumnDescriptor[] columnDescriptors,
591 Object[] row =
new Object[columnDescriptors.length + 1];
592 row[0] = instance.getId();
594 for (ColumnDescriptor columnDescriptor: columnDescriptors) {
595 row[j++] = columnDescriptor.getFieldValue(instance);
601 protected List<Object[]>
readFromJDBC(ColumnDescriptor[] columnDescriptors) {
603 List<Object[]> result =
new ArrayList<Object[]>();
604 Set<Object[]> rows =
new TreeSet<Object[]>(
new Comparator<Object[]>(){
605 public int compare(Object[] me, Object[] other) {
606 return ((Integer)me[0]) - ((Integer)other[0]);
610 for (ColumnDescriptor columnDescriptor: columnDescriptors) {
612 buffer.append(columnDescriptor.getColumnName());
614 buffer.append(
" FROM ");
615 buffer.append(tableName);
617 if (debug) System.out.println(statement);
618 PreparedStatement preparedStatement = null;
621 preparedStatement = connection.prepareStatement(statement);
622 ResultSet rs = preparedStatement.executeQuery();
624 Object[] row =
new Object[columnDescriptors.length + 1];
626 row[0] = rs.getInt(1);
627 for (ColumnDescriptor columnDescriptor: columnDescriptors) {
628 row[j] = columnDescriptor.getResultSetValue(rs, j + 1);
635 }
catch (SQLException e) {
636 throw new RuntimeException(
"Failed to read " + tableName +
" at instance " + i, e);
638 result =
new ArrayList<Object[]>(rows);
639 if (debug) System.out.println(
"readFromJDBC: " + dumpListOfObjectArray(result));
643 @SuppressWarnings(
"unchecked")
644 protected <T> T proxyFor (final Class<T> cls) {
645 InvocationHandler
handler =
new InvocationHandler() {
646 private Map<String, Object> values =
new HashMap<String, Object>();
647 public Object invoke(Object instance, Method method, Object[] args)
649 String methodName = method.getName();
650 String propertyName = methodName.substring(3);
651 String methodPrefix = methodName.substring(0, 3);
652 if (
"get".equals(methodPrefix)) {
653 return values.get(propertyName);
654 }
else if (
"set".equals(methodPrefix)) {
655 values.put(propertyName, args[0]);
659 throw new RuntimeException(
"Not a get/set method: " + methodName);
663 Object proxy = Proxy.newProxyInstance(
loader,
new Class[] {cls}, handler);
671 protected static class ColumnDescriptor {
673 private String columnName;
675 protected InstanceHandler instanceHandler;
677 public String getColumnName() {
681 public Object getResultSetValue(ResultSet rs,
int j)
throws SQLException {
682 return instanceHandler.getResultSetValue(rs, j);
685 public Object getFieldValue(IdBase instance) {
686 return instanceHandler.getFieldValue(instance);
689 public void setFieldValue(IdBase instance, Object value) {
690 this.instanceHandler.setFieldValue(instance, value);
693 public void setPreparedStatementValue(PreparedStatement preparedStatement,
int j, Object value)
694 throws SQLException {
695 instanceHandler.setPreparedStatementValue(preparedStatement, j, value);
698 public ColumnDescriptor(
String name, InstanceHandler instanceHandler) {
699 this.columnName =
name;
700 this.instanceHandler = instanceHandler;
705 void setFieldValue(
IdBase instance, Object value);
706 Object getResultSetValue(ResultSet rs,
int j)
708 Object getFieldValue(
IdBase instance);
709 public void setPreparedStatementValue(PreparedStatement preparedStatement,
int j, Object value)
714 int a1factor = 1 + number/a1values.length;
715 return a1values[index/a1factor];
718 protected String getA3for(
long i) {
719 return "employeenumber=100000" +
i;
722 protected void createAllPrimitivesInstances(
int number) {
723 createAllPrimitivesInstances(session, number);
726 protected void createAllPrimitivesInstances(Session session,
int number) {
727 for (
int i = 0;
i < number; ++
i) {
728 AllPrimitives instance = createAllPrimitiveInstance(session,
i);
729 instances.add(instance);
733 protected AllPrimitives createAllPrimitiveInstance(Session session,
int i) {
734 AllPrimitives instance = session.newInstance(AllPrimitives.class, i);
735 initialize(instance, i);
739 protected void initialize(AllPrimitives instance,
int i) {
740 instance.setInt_not_null_hash(i);
741 instance.setInt_not_null_btree(i);
742 instance.setInt_not_null_both(i);
743 instance.setInt_not_null_none(i);
744 instance.setInt_null_hash(i);
745 instance.setInt_null_btree(i);
746 instance.setInt_null_both(i);
747 instance.setInt_null_none(i);
749 instance.setLong_not_null_hash((
long)i);
750 instance.setLong_not_null_btree((
long)i);
751 instance.setLong_not_null_both((
long)i);
752 instance.setLong_not_null_none((
long)i);
753 instance.setLong_null_hash((
long)i);
754 instance.setLong_null_btree((
long)i);
755 instance.setLong_null_both((
long)i);
756 instance.setLong_null_none((
long)i);
758 instance.setByte_not_null_hash((byte)i);
759 instance.setByte_not_null_btree((byte)i);
760 instance.setByte_not_null_both((byte)i);
761 instance.setByte_not_null_none((byte)i);
762 instance.setByte_null_hash((byte)i);
763 instance.setByte_null_btree((byte)i);
764 instance.setByte_null_both((byte)i);
765 instance.setByte_null_none((byte)i);
767 instance.setShort_not_null_hash((
short)i);
768 instance.setShort_not_null_btree((
short)i);
769 instance.setShort_not_null_both((
short)i);
770 instance.setShort_not_null_none((
short)i);
771 instance.setShort_null_hash((
short)i);
772 instance.setShort_null_btree((
short)i);
773 instance.setShort_null_both((
short)i);
774 instance.setShort_null_none((
short)i);
777 protected static Object[] setupDn2idPK() {
778 Object[] result =
new Object[16];
779 result[0] =
"dc=com";
781 result[1] =
"dc=example";
782 result[2] =
"ou=people";