OSDN Git Service

DBFlute-0.9.3に更新
[ea2ddl/ea2ddl.git] / ea2ddl-dao / src / main / java / jp / sourceforge / ea2ddl / dao / allcommon / s2dao / internal / sqlcommand / InternalUpdateAutoDynamicCommand.java
1 package jp.sourceforge.ea2ddl.dao.allcommon.s2dao.internal.sqlcommand;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.List;\r
5 \r
6 import javax.sql.DataSource;\r
7 \r
8 import org.seasar.extension.jdbc.PropertyType;\r
9 import org.seasar.extension.jdbc.StatementFactory;\r
10 import org.seasar.dao.impl.AbstractSqlCommand;\r
11 import org.seasar.dao.BeanMetaData;\r
12 import org.seasar.dao.NoUpdatePropertyTypeRuntimeException;\r
13 \r
14 import jp.sourceforge.ea2ddl.dao.allcommon.s2dao.internal.sqlhandler.InternalUpdateAutoHandler;\r
15 \r
16 /**\r
17  * @author DBFlute(AutoGenerator)\r
18  */\r
19 public class InternalUpdateAutoDynamicCommand extends AbstractSqlCommand {\r
20 \r
21         // ===================================================================================\r
22     //                                                                          Definition\r
23     //                                                                          ==========\r
24     /** Log instance. */\r
25     private static final org.apache.commons.logging.Log _log = org.apache.commons.logging.LogFactory.getLog(InternalUpdateAutoDynamicCommand.class);\r
26 \r
27     private static final Integer NO_UPDATE = new Integer(0);\r
28 \r
29         // ===================================================================================\r
30     //                                                                           Attribute\r
31     //                                                                           =========\r
32     private BeanMetaData beanMetaData;\r
33     private String[] propertyNames;\r
34     private boolean checkSingleRowUpdate = true;\r
35     private boolean versionNoAutoIncrementOnMemory = true;\r
36 \r
37         // ===================================================================================\r
38     //                                                                         Constructor\r
39     //                                                                         ===========\r
40     public InternalUpdateAutoDynamicCommand(DataSource dataSource, StatementFactory statementFactory) {\r
41         super(dataSource, statementFactory);\r
42     }\r
43 \r
44         // ===================================================================================\r
45     //                                                                             Execute\r
46     //                                                                             =======\r
47     public Object execute(Object[] args) {\r
48         final Object bean = args[0];\r
49         final BeanMetaData bmd = getBeanMetaData();\r
50         final PropertyType[] propertyTypes = createUpdatePropertyTypes(bmd, bean, getPropertyNames());\r
51         if (propertyTypes.length == 0) {\r
52             if (_log.isDebugEnabled()) {\r
53                 _log.debug(createNoUpdateLogMessage(bean, bmd));\r
54             }\r
55             return NO_UPDATE;\r
56         }\r
57         InternalUpdateAutoHandler handler = createInternalUpdateAutoHandler(bmd, propertyTypes);\r
58         handler.setSql(createUpdateSql(bmd, propertyTypes, bean));\r
59         handler.setLoggingMessageSqlArgs(args);\r
60         int i = handler.execute(args);\r
61 \r
62         // [Comment Out]: This statement moved to the handler at [DBFlute-0.8.0].\r
63         // if (isCheckSingleRowUpdate() && i < 1) {\r
64         //     throw createNotSingleRowUpdatedRuntimeException(args[0], i);\r
65         // }\r
66 \r
67         return new Integer(i);\r
68     }\r
69 \r
70     protected InternalUpdateAutoHandler createInternalUpdateAutoHandler(BeanMetaData bmd, PropertyType[] propertyTypes) {\r
71         InternalUpdateAutoHandler handler = new InternalUpdateAutoHandler(getDataSource(), getStatementFactory(), bmd, propertyTypes);\r
72         handler.setVersionNoAutoIncrementOnMemory(versionNoAutoIncrementOnMemory);\r
73         handler.setCheckSingleRowUpdate(isCheckSingleRowUpdate()); // [DBFlute-0.8.0]\r
74         return handler;\r
75     }\r
76 \r
77     protected PropertyType[] createUpdatePropertyTypes(BeanMetaData bmd, Object bean, String[] propertyNames) {\r
78         final List<PropertyType> types = new ArrayList<PropertyType>();\r
79         final String timestampPropertyName = bmd.getTimestampPropertyName();\r
80         final String versionNoPropertyName = bmd.getVersionNoPropertyName();\r
81         for (int i = 0; i < propertyNames.length; ++i) {\r
82             PropertyType pt = bmd.getPropertyType(propertyNames[i]);\r
83             if (pt.isPrimaryKey() == false) {\r
84                 String propertyName = pt.getPropertyName();\r
85                 if (propertyName.equalsIgnoreCase(timestampPropertyName)\r
86                         || propertyName.equalsIgnoreCase(versionNoPropertyName)\r
87                         || pt.getPropertyDesc().getValue(bean) != null) {\r
88                     types.add(pt);\r
89                 }\r
90             }\r
91         }\r
92         if (types.isEmpty()) {\r
93             throw new NoUpdatePropertyTypeRuntimeException();\r
94         }\r
95         PropertyType[] propertyTypes = (PropertyType[]) types.toArray(new PropertyType[types.size()]);\r
96         return propertyTypes;\r
97     }\r
98 \r
99     protected String createNoUpdateLogMessage(final Object bean, final BeanMetaData bmd) {\r
100         final StringBuffer sb = new StringBuffer();\r
101         sb.append("skip UPDATE: table=").append(bmd.getTableName());\r
102         final int size = bmd.getPrimaryKeySize();\r
103         for (int i = 0; i < size; i++) {\r
104             if (i == 0) {\r
105                 sb.append(", key{");\r
106             } else {\r
107                 sb.append(", ");\r
108             }\r
109             final String keyName = bmd.getPrimaryKey(i);\r
110             sb.append(keyName).append("=");\r
111             sb.append(bmd.getPropertyTypeByColumnName(keyName).getPropertyDesc().getValue(bean));\r
112             if (i == size - 1) {\r
113                 sb.append("}");\r
114             }\r
115         }\r
116         final String s = new String(sb);\r
117         return s;\r
118     }\r
119 \r
120     /**\r
121      * Create update SQL. The update is by the primary keys.\r
122      * @param bmd The meta data of bean. (NotNull & RequiredPrimaryKeys)\r
123      * @param propertyTypes The types of property for update. (NotNull)\r
124      * @param bean A bean for update for handling version no and so on. (NotNull)\r
125      * @return The update SQL. (NotNull)\r
126      */\r
127     protected String createUpdateSql(BeanMetaData bmd, PropertyType[] propertyTypes, Object bean) {\r
128         if (bmd.getPrimaryKeySize() == 0) {\r
129             String msg = "The table '" + bmd.getTableName() + "' does not have primary keys!";\r
130             throw new IllegalStateException(msg);\r
131         }\r
132         final StringBuilder sb = new StringBuilder(100);\r
133         sb.append("update ");\r
134         sb.append(bmd.getTableName());\r
135         sb.append(" set ");\r
136         final String versionNoPropertyName = bmd.getVersionNoPropertyName();\r
137         for (int i = 0; i < propertyTypes.length; ++i) {\r
138             PropertyType pt = propertyTypes[i];\r
139             final String columnName = pt.getColumnName();\r
140             if (i > 0) {\r
141                 sb.append(", ");\r
142             }\r
143             if (pt.getPropertyName().equalsIgnoreCase(versionNoPropertyName)) {\r
144                 if (!isVersionNoAutoIncrementOnMemory()) {\r
145                     setupVersionNoAutoIncrementOnQuery(sb, columnName);\r
146                     continue;\r
147                 }\r
148                 final Object versionNo = pt.getPropertyDesc().getValue(bean);\r
149                 if (versionNo == null) {\r
150                     setupVersionNoAutoIncrementOnQuery(sb, columnName);\r
151                     continue;\r
152                 }\r
153             }\r
154             sb.append(columnName).append(" = ?");\r
155         }\r
156         sb.append(" where ");\r
157         for (int i = 0; i < bmd.getPrimaryKeySize(); ++i) {\r
158             sb.append(bmd.getPrimaryKey(i)).append(" = ? and ");\r
159         }\r
160         sb.setLength(sb.length() - 5);\r
161         if (bmd.hasVersionNoPropertyType()) {\r
162             PropertyType pt = bmd.getVersionNoPropertyType();\r
163             sb.append(" and ").append(pt.getColumnName()).append(" = ?");\r
164         }\r
165         if (bmd.hasTimestampPropertyType()) {\r
166             PropertyType pt = bmd.getTimestampPropertyType();\r
167             sb.append(" and ").append(pt.getColumnName()).append(" = ?");\r
168         }\r
169         return sb.toString();\r
170     }\r
171 \r
172     protected boolean isVersionNoAutoIncrementOnMemory() {\r
173         return versionNoAutoIncrementOnMemory;\r
174     }\r
175 \r
176     public void setVersionNoAutoIncrementOnMemory(boolean versionNoAutoIncrementOnMemory) {\r
177         this.versionNoAutoIncrementOnMemory = versionNoAutoIncrementOnMemory;\r
178     }\r
179     \r
180     protected void setupVersionNoAutoIncrementOnQuery(StringBuilder sb, String columnName) {\r
181         sb.append(columnName).append(" = ").append(columnName).append(" + 1");\r
182     }\r
183 \r
184     public BeanMetaData getBeanMetaData() {\r
185         return beanMetaData;\r
186     }\r
187 \r
188     public void setBeanMetaData(BeanMetaData beanMetaData) {\r
189         this.beanMetaData = beanMetaData;\r
190     }\r
191 \r
192     public String[] getPropertyNames() {\r
193         return propertyNames;\r
194     }\r
195 \r
196     public void setPropertyNames(String[] propertyNames) {\r
197         this.propertyNames = propertyNames;\r
198     }\r
199 \r
200     public boolean isCheckSingleRowUpdate() {\r
201         return checkSingleRowUpdate;\r
202     }\r
203 \r
204     public void setCheckSingleRowUpdate(boolean resultCheck) {\r
205         this.checkSingleRowUpdate = resultCheck;\r
206     }\r
207 }\r