View Javadoc
1   /*
2    * Copyright 2002-2013 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.jdbc.core.simple;
18  
19  import java.sql.Connection;
20  import java.sql.DatabaseMetaData;
21  import java.sql.ResultSet;
22  import java.sql.Types;
23  import java.util.ArrayList;
24  import java.util.Date;
25  import java.util.List;
26  import javax.sql.DataSource;
27  
28  import org.junit.Before;
29  import org.junit.Test;
30  
31  import org.springframework.jdbc.core.SqlParameterValue;
32  import org.springframework.jdbc.core.metadata.TableMetaDataContext;
33  import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
34  
35  import static org.junit.Assert.*;
36  import static org.mockito.BDDMockito.*;
37  
38  /**
39   * Mock object based tests for TableMetaDataContext.
40   *
41   * @author Thomas Risberg
42   */
43  public class TableMetaDataContextTests  {
44  
45  	private Connection connection;
46  	private DataSource dataSource;
47  	private DatabaseMetaData databaseMetaData;
48  
49  	private TableMetaDataContext context = new TableMetaDataContext();
50  
51  	@Before
52  	public void setUp() throws Exception {
53  		connection = mock(Connection.class);
54  		dataSource = mock(DataSource.class);
55  		databaseMetaData = mock(DatabaseMetaData.class);
56  		given(connection.getMetaData()).willReturn(databaseMetaData);
57  		given(dataSource.getConnection()).willReturn(connection);
58  	}
59  
60  	public void verifyClosed() throws Exception {
61  		verify(connection).close();
62  	}
63  
64  	@Test
65  	public void testMatchInParametersAndSqlTypeInfoWrapping() throws Exception {
66  		final String TABLE = "customers";
67  		final String USER = "me";
68  
69  		ResultSet metaDataResultSet = mock(ResultSet.class);
70  		given(metaDataResultSet.next()).willReturn(true, false);
71  		given(metaDataResultSet.getString("TABLE_SCHEM")).willReturn(USER);
72  		given(metaDataResultSet.getString("TABLE_NAME")).willReturn(TABLE);
73  		given(metaDataResultSet.getString("TABLE_TYPE")).willReturn("TABLE");
74  
75  		ResultSet columnsResultSet = mock(ResultSet.class);
76  		given(columnsResultSet.next()).willReturn(
77  				true, true, true, true, false);
78  		given(columnsResultSet.getString("COLUMN_NAME")).willReturn(
79  				"id", "name", "customersince", "version");
80  		given(columnsResultSet.getInt("DATA_TYPE")).willReturn(
81  				Types.INTEGER, Types.VARCHAR, Types.DATE, Types.NUMERIC);
82  		given(columnsResultSet.getBoolean("NULLABLE")).willReturn(
83  				false, true, true, false);
84  
85  		given(databaseMetaData.getDatabaseProductName()).willReturn("MyDB");
86  		given(databaseMetaData.getDatabaseProductName()).willReturn("1.0");
87  		given(databaseMetaData.getUserName()).willReturn(USER);
88  		given(databaseMetaData.storesLowerCaseIdentifiers()).willReturn(true);
89  		given(databaseMetaData.getTables(null, null, TABLE, null)).willReturn(metaDataResultSet);
90  		given(databaseMetaData.getColumns(null, USER, TABLE, null)).willReturn(columnsResultSet);
91  
92  		MapSqlParameterSource map = new MapSqlParameterSource();
93  		map.addValue("id", 1);
94  		map.addValue("name", "Sven");
95  		map.addValue("customersince", new Date());
96  		map.addValue("version", 0);
97  		map.registerSqlType("customersince", Types.DATE);
98  		map.registerSqlType("version", Types.NUMERIC);
99  
100 		context.setTableName(TABLE);
101 		context.processMetaData(dataSource, new ArrayList<String>(), new String[] {});
102 
103 		List<Object> values = context.matchInParameterValuesWithInsertColumns(map);
104 
105 		assertEquals("wrong number of parameters: ", 4, values.size());
106 		assertTrue("id not wrapped with type info", values.get(0) instanceof Number);
107 		assertTrue("name not wrapped with type info", values.get(1) instanceof String);
108 		assertTrue("date wrapped with type info",
109 				values.get(2) instanceof SqlParameterValue);
110 		assertTrue("version wrapped with type info",
111 				values.get(3) instanceof SqlParameterValue);
112 		verify(metaDataResultSet, atLeastOnce()).next();
113 		verify(columnsResultSet, atLeastOnce()).next();
114 		verify(metaDataResultSet).close();
115 		verify(columnsResultSet).close();
116 	}
117 
118 	@Test
119 	public void testTableWithSingleColumnGeneratedKey() throws Exception {
120 		final String TABLE = "customers";
121 		final String USER = "me";
122 
123 		ResultSet metaDataResultSet = mock(ResultSet.class);
124 		given(metaDataResultSet.next()).willReturn(true, false);
125 		given(metaDataResultSet.getString("TABLE_SCHEM")).willReturn(USER);
126 		given(metaDataResultSet.getString("TABLE_NAME")).willReturn(TABLE);
127 		given(metaDataResultSet.getString("TABLE_TYPE")).willReturn("TABLE");
128 
129 		ResultSet columnsResultSet = mock(ResultSet.class);
130 		given(columnsResultSet.next()).willReturn(true, false);
131 		given(columnsResultSet.getString("COLUMN_NAME")).willReturn("id");
132 		given(columnsResultSet.getInt("DATA_TYPE")).willReturn(Types.INTEGER);
133 		given(columnsResultSet.getBoolean("NULLABLE")).willReturn(false);
134 
135 		given(databaseMetaData.getDatabaseProductName()).willReturn("MyDB");
136 		given(databaseMetaData.getDatabaseProductName()).willReturn("1.0");
137 		given(databaseMetaData.getUserName()).willReturn(USER);
138 		given(databaseMetaData.storesLowerCaseIdentifiers()).willReturn(true);
139 		given(databaseMetaData.getTables(null, null, TABLE, null)).willReturn(metaDataResultSet);
140 		given(databaseMetaData.getColumns(null, USER, TABLE, null)).willReturn(columnsResultSet);
141 
142 		MapSqlParameterSource map = new MapSqlParameterSource();
143 		String[] keyCols = new String[] { "id" };
144 		context.setTableName(TABLE);
145 		context.processMetaData(dataSource, new ArrayList<String>(), keyCols);
146 		List<Object> values = context.matchInParameterValuesWithInsertColumns(map);
147 		String insertString = context.createInsertString(keyCols);
148 
149 		assertEquals("wrong number of parameters: ", 0, values.size());
150 		assertEquals("empty insert not generated correctly", "INSERT INTO customers () VALUES()", insertString);
151 		verify(metaDataResultSet, atLeastOnce()).next();
152 		verify(columnsResultSet, atLeastOnce()).next();
153 		verify(metaDataResultSet).close();
154 		verify(columnsResultSet).close();
155 	}
156 }