View Javadoc
1   package guru.mikelue.jdut.vendor.mssql;
2   
3   import java.sql.Connection;
4   import java.sql.SQLException;
5   import java.util.Optional;
6   
7   import org.slf4j.Logger;
8   import org.slf4j.LoggerFactory;
9   
10  import guru.mikelue.jdut.datagrain.DataRow;
11  import guru.mikelue.jdut.datagrain.SchemaTable;
12  import guru.mikelue.jdut.jdbc.JdbcTemplateFactory;
13  import guru.mikelue.jdut.operation.DataRowOperator;
14  
15  /**
16   * Used to surrounding {@link DataRowOperator} for supporting insertion of identity for table.
17   */
18  public class IdentityInsertOperator implements DataRowOperator {
19  	private Logger logger = LoggerFactory.getLogger(IdentityInsertOperator.class);
20  
21  	/**
22  	 * Used as flag to indicate the current data row has data of identity column.
23  	 */
24  	private final static String HAS_IDENTITY_COLUMN = "_mssql_has_identity_column_";
25  
26  	/**
27  	 * Checks whether or not a data row has identity data.
28  	 *
29  	 * @param dataRow The data row to be checked
30  	 *
31  	 * @return true if it does
32  	 */
33  	public static boolean hasIdentityColumn(DataRow dataRow)
34  	{
35  		return dataRow.getAttribute(HAS_IDENTITY_COLUMN);
36  	}
37  	/**
38  	 * Checks whether or not the table of data row has enabled identity.<br>
39  	 *
40  	 * If it is unknown, this method gives <em>true value</em>.
41  	 *
42  	 * @param dataRow The data row to be checked
43  	 *
44  	 * @return true if it does
45  	 */
46  	public static boolean identityChecked(DataRow dataRow)
47  	{
48  		return dataRow.hasAttribute(HAS_IDENTITY_COLUMN);
49  	}
50  
51  	private final DataRowOperator op;
52  
53  	/**
54  	 * As function interface of {@link DataRowOperator.SurroundOperator}.
55  	 *
56  	 * @param newOperator The operator to be surrounded
57  	 *
58  	 * @see DataRowOperator
59  	 */
60  	public IdentityInsertOperator(DataRowOperator newOperator)
61  	{
62  		op = newOperator;
63  	}
64  
65  	/**
66  	 * {@inheritDoc}
67  	 */
68  	@Override
69  	public DataRowkelue/jdut/datagrain/DataRow.html#DataRow">DataRow operate(Connection connection, DataRow dataRow) throws SQLException
70  	{
71  		SchemaTable table = dataRow.getTable();
72  
73  		/**
74  		 * Initialize flags for identity data
75  		 */
76  		if (!identityChecked(dataRow)) {
77  			dataRow.putAttribute(
78  				HAS_IDENTITY_COLUMN,
79  				dataRow.getColumns().stream()
80  					.anyMatch(columnName -> {
81  						Optional<Boolean> autoIncremental = table.getColumn(columnName).getAutoIncremental();
82  						return autoIncremental.isPresent() && autoIncremental.get();
83  					})
84  			);
85  		}
86  		// :~)
87  
88  		/**
89  		 * Executes the enabled identity insert command to the table
90  		 */
91  		if (hasIdentityColumn(dataRow)) {
92  			JdbcTemplateFactory.buildRunnable(
93  				() -> connection.createStatement(),
94  				stat -> stat.executeUpdate(String.format(
95  					"SET IDENTITY_INSERT %s ON",
96  					table.getQuotedFullName()
97  				))
98  			).runJdbc();
99  		}
100 		// :~)
101 
102 		DataRow result = op.operate(connection, dataRow);
103 
104 		/**
105 		 * Disable identity insert
106 		 */
107 		if (hasIdentityColumn(dataRow)) {
108 			logger.debug("[MS SQL Server] Enable identity: \"{}\"", table.getName());
109 			JdbcTemplateFactory.buildRunnable(
110 				() -> connection.createStatement(),
111 				stat -> stat.executeUpdate(String.format(
112 					"SET IDENTITY_INSERT %s OFF",
113 					table.getQuotedFullName()
114 				))
115 			).runJdbc();
116 		}
117 		// :~)
118 
119 		return result;
120 	}
121 }