Clover.NET coverage report - Coverage for s2dao.net

Coverage timestamp: 2006年5月18日 15:09:15

File Stats: LOC: 568   Methods: 37
NCLOC: 492 Classes: 1
 
Source File Conditionals Statements Methods TOTAL
Seasar.Dao.Impl\DaoMetaDataImpl.cs 60.5% 68.5% 78.4% 67.2%
coverage coverage
1   #region Copyright
2   /*
3   * Copyright 2005 the Seasar Foundation and the Others.
4   *
5   * Licensed under the Apache License, Version 2.0 (the "License");
6   * you may not use this file except in compliance with the License.
7   * You may obtain a copy of the License at
8   *
9   * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
14   * either express or implied. See the License for the specific language
15   * governing permissions and limitations under the License.
16   */
17   #endregion
18  
19   using System;
20   using System.Collections;
21   using System.Data;
22   using System.Reflection;
23   using System.Text;
24   using System.Text.RegularExpressions;
25   using Seasar.Dao.Dbms;
26   using Seasar.Extension.ADO;
27   using Seasar.Extension.ADO.Impl;
28   using Seasar.Extension.ADO.Types;
29   using Seasar.Framework.Beans;
30   using Seasar.Framework.Util;
31  
32   namespace Seasar.Dao.Impl
33   {
34   public class DaoMetaDataImpl : IDaoMetaData
35   {
36   private static readonly Regex startWithOrderByPattern =
37   new Regex("(/\\[^*]+\\*/)*order by",RegexOptions.IgnoreCase);
38  
39   private static readonly string[] INSERT_NAMES = new string[]
40   { "Insert", "Create", "Add" };
41  
42   private static readonly string[] UPDATE_NAMES = new string[]
43   { "Update", "Modify", "Store" };
44  
45   private static readonly string[] DELETE_NAMES = new string[]
46   { "Delete", "Remove" };
47  
48   private const string NOT_SINGLE_ROW_UPDATED = "NotSingleRowUpdated";
49  
50   protected Type daoType;
51   protected Type daoInterface;
52   protected IDataSource dataSource;
53   protected IDaoAnnotationReader annotationReader;
54   protected ICommandFactory commandFactory;
55   protected IDataReaderFactory dataReaderFactory;
56   protected IDbms dbms;
57   protected Type beanType;
58   protected IBeanMetaData beanMetaData;
59   protected Hashtable sqlCommands = new Hashtable();
60  
61 18 public DaoMetaDataImpl(Type daoType, IDataSource dataSource,ICommandFactory commandFactory,
62   IDataReaderFactory dataReaderFactory, IDatabaseMetaData dbMetaData)
63   {
64 18 this.daoType = daoType;
65 18 daoInterface = GetDaoInterface(daoType);
66 18 annotationReader = new FieldAnnotationReader(daoType);
67 18 beanType = annotationReader.GetBeanType();
68 18 this.dataSource = dataSource;
69  
70 18 this.commandFactory = commandFactory;
71 18 this.dataReaderFactory = dataReaderFactory;
72 18 dbms = DbmsManager.GetDbms(dataSource);
73 18 beanMetaData = new BeanMetaDataImpl(beanType, dbMetaData, dbms);
74 18 SetupSqlCommand();
75   }
76  
77 18 protected void SetupSqlCommand()
78   {
79 18 MethodInfo[] allMethods = daoInterface.GetMethods();
80 18 Hashtable names = new Hashtable();
81 18 foreach(MethodInfo mi in allMethods)
82   {
83 116 names[mi.Name] = mi;
84   }
85 18 IDictionaryEnumerator enu = names.GetEnumerator();
86 134 while(enu.MoveNext())
87   {
88 116 try
89   {
90 116 MethodInfo method = daoType.GetMethod((string) enu.Key);
91 116 if(method.IsAbstract) SetupMethod(method);
92   }
93   catch(AmbiguousMatchException) {}
94   }
95   }
96  
97 116 protected void SetupMethod(MethodInfo mi)
98   {
99 116 string sql = null;
100 116 sql = annotationReader.GetSql(mi.Name, dbms);
101 116 if(sql != null)
102   {
103 5 SetupMethodByManual(mi, sql);
104 5 return;
105   }
106 111 string baseName = daoInterface.FullName + "_" + mi.Name;
107 111 string dbmsPath = baseName + dbms.Suffix + ".sql";
108 111 string standardPath = baseName + ".sql";
109 111 Assembly asm = daoInterface.Assembly;
110  
111 111 if(ResourceUtil.IsExist(dbmsPath, asm))
112   {
113 0 sql = TextUtil.ReadText(dbmsPath, asm);
114 0 SetupMethodByManual(mi, sql);
115   }
116 111 else if(ResourceUtil.IsExist(standardPath, asm))
117   {
118 5 sql = TextUtil.ReadText(standardPath, asm);
119 5 SetupMethodByManual(mi, sql);
120   }
121   else
122   {
123 106 SetupMethodByAuto(mi);
124   }
125   }
126  
127 10 protected void SetupMethodByManual(MethodInfo mi, string sql)
128   {
129 10 if(IsSelect(mi))
130   {
131 5 SetupSelectMethodByManual(mi, sql);
132   }
133   else
134   {
135 5 SetupUpdateMethodByManual(mi, sql);
136   }
137   }
138  
139 106 protected void SetupMethodByAuto(MethodInfo mi)
140   {
141 106 if(IsInsert(mi.Name))
142   {
143 27 SetupInsertMethodByAuto(mi);
144   }
145 79 else if(IsUpdate(mi.Name))
146   {
147 30 SetupUpdateMethodByAuto(mi);
148   }
149 49 else if(IsDelete(mi.Name))
150   {
151 11 SetupDeleteMethodByAuto(mi);
152   }
153   else
154   {
155 38 SetupSelectMethodByAuto(mi);
156   }
157   }
158  
159 5 protected void SetupSelectMethodByManual(MethodInfo mi, string sql)
160   {
161 5 SelectDynamicCommand cmd = CreateSelectDynamicCommand(CreateDataReaderHandler(mi));
162 5 cmd.Sql = sql;
163 5 cmd.ArgNames = MethodUtil.GetParameterNames(mi);
164 5 cmd.ArgTypes = MethodUtil.GetParameterTypes(mi);
165 5 sqlCommands[mi.Name] = cmd;
166   }
167  
168 43 protected SelectDynamicCommand CreateSelectDynamicCommand(IDataReaderHandler drh)
169   {
170 43 return new SelectDynamicCommand(dataSource, commandFactory, drh, dataReaderFactory);
171   }
172  
173 33 protected SelectDynamicCommand CreateSelectDynamicCommand(
174   IDataReaderHandler dataReaderHandler, string query)
175   {
176 33 SelectDynamicCommand cmd = CreateSelectDynamicCommand(dataReaderHandler);
177 33 StringBuilder buf = new StringBuilder(255);
178 33 if(StartsWithSelect(query))
179 0 buf.Append(query);
180   else
181   {
182 33 string sql = dbms.GetAutoSelectSql(BeanMetaData);
183 33 buf.Append(sql);
184 33 if(query != null)
185   {
186 33 if(StartsWithOrderBy(query))
187 0 buf.Append(" ");
188 33 else if(sql.LastIndexOf("WHERE") < 0)
189 33 buf.Append(" WHERE ");
190   else
191 0 buf.Append(" AND ");
192 33 buf.Append(query);
193   }
194   }
195 33 cmd.Sql = buf.ToString();
196 33 return cmd;
197   }
198  
199 33 protected static bool StartsWithSelect(string query)
200   {
201 33 return StringUtil.StartWith(query, "select");
202   }
203  
204 66 protected static bool StartsWithOrderBy(string query)
205   {
206 66 if(query != null)
207   {
208 0 if(query.Trim().ToLower().StartsWith("order by")) return true;
209   //Match m = startWithOrderByPattern.Match(query);
210   //if(m.Success) return true;
211   }
212 66 return false;
213   }
214  
215 43 protected IDataReaderHandler CreateDataReaderHandler(MethodInfo mi)
216   {
217 43 if (mi.ReturnType.IsArray)
218 0 return new BeanArrayMetaDataDataReaderHandler(beanMetaData);
219 43 else if(typeof(IList).IsAssignableFrom(mi.ReturnType))
220 26 return new BeanListMetaDataDataReaderHandler(beanMetaData);
221 17 else if(IsBeanTypeAssignable(mi.ReturnType))
222 12 return new BeanMetaDataDataReaderHandler(beanMetaData);
223 5 else if(Array.CreateInstance(beanType, 0).GetType()
224   .IsAssignableFrom(mi.ReturnType))
225 0 return new BeanArrayMetaDataDataReaderHandler(beanMetaData);
226   else
227 5 return new ObjectDataReaderHandler();
228   }
229  
230 153 protected bool IsBeanTypeAssignable(Type type)
231   {
232 153 return beanType.IsAssignableFrom(type) ||
233   type.IsAssignableFrom(beanType);
234   }
235  
236 5 protected void SetupUpdateMethodByManual(MethodInfo mi, string sql)
237   {
238 5 UpdateDynamicCommand cmd = new UpdateDynamicCommand(dataSource, commandFactory);
239 5 cmd.Sql = sql;
240 5 string[] argNames = MethodUtil.GetParameterNames(mi);
241 5 if(argNames.Length == 0 && IsUpdateSignatureForBean(mi))
242 0 argNames = new string[] { StringUtil.Decapitalize(beanType.Name) };
243 5 cmd.ArgNames = argNames;
244 5 cmd.ArgTypes = MethodUtil.GetParameterTypes(mi);
245   // cmd.NotSingleRowUpdatedExceptionType = GetNotSingleRowUpdatedExceptionType(mi);
246 5 sqlCommands[mi.Name] = cmd;
247   }
248  
249 68 protected bool IsUpdateSignatureForBean(MethodInfo mi)
250   {
251 68 Type[] paramTypes = MethodUtil.GetParameterTypes(mi);
252 68 return paramTypes.Length == 1
253   && IsBeanTypeAssignable(paramTypes[0]);
254   }
255  
256   // protected Type GetNotSingleRowUpdatedExceptionType(MethodInfo mi)
257   // {
258   // }
259  
260 27 protected void SetupInsertMethodByAuto(MethodInfo mi)
261   {
262 27 CheckAutoUpdateMethod(mi);
263 27 string[] propertyNames = GetPersistentPropertyNames(mi.Name);
264 27 ISqlCommand cmd = null;
265 27 if(IsUpdateSignatureForBean(mi))
266 27 cmd = new InsertAutoStaticCommand(dataSource, commandFactory,
267   beanMetaData, propertyNames);
268   else
269 0 throw new NotSupportedException("InsertBatchAutoStaticCommand");
270 27 sqlCommands[mi.Name] = cmd;
271   }
272  
273 30 protected void SetupUpdateMethodByAuto(MethodInfo mi)
274   {
275 30 CheckAutoUpdateMethod(mi);
276 30 string[] propertyNames = GetPersistentPropertyNames(mi.Name);
277 30 AbstractSqlCommand cmd = null;
278 30 if(IsUpdateSignatureForBean(mi))
279 30 cmd = new UpdateAutoStaticCommand(dataSource, commandFactory,
280   beanMetaData, propertyNames);
281   else
282 0 throw new NotSupportedException("UpdateBatchAutoStaticCommand");
283  
284 30 sqlCommands[mi.Name] = cmd;
285   }
286  
287 11 protected void SetupDeleteMethodByAuto(MethodInfo mi)
288   {
289 11 CheckAutoUpdateMethod(mi);
290 11 string[] propertyNames = GetPersistentPropertyNames(mi.Name);
291 11 ISqlCommand cmd = null;
292 11 if(IsUpdateSignatureForBean(mi))
293 11 cmd = new DeleteAutoStaticCommand(dataSource, commandFactory,
294   beanMetaData, propertyNames);
295   else
296 0 throw new NotSupportedException("DeleteBatchAutoStaticCommand");
297 11 sqlCommands[mi.Name] = cmd;
298   }
299  
300 68 protected string[] GetPersistentPropertyNames(string methodName)
301   {
302 68 ArrayList names = new ArrayList();
303 68 string[] props = annotationReader.GetNoPersistentProps(methodName);
304 68 if(props != null)
305   {
306 126 for(int i = 0; i < beanMetaData.PropertyTypeSize; ++i)
307   {
308 112 IPropertyType pt = beanMetaData.GetPropertyType(i);
309 112 if(pt.IsPersistent
310   && !IsPropertyExist(props, pt.PropertyName))
311 84 names.Add(pt.PropertyName);
312   }
313   }
314   else
315   {
316 54 props = annotationReader.GetPersistentProps(methodName);
317 54 if(props != null)
318   {
319  
320 14 foreach(string prop in props) names.Add(prop);
321 28 for(int i = 0; i < beanMetaData.PrimaryKeySize; ++i)
322   {
323 14 string pk = beanMetaData.GetPrimaryKey(i);
324 14 IPropertyType pt = beanMetaData.GetPropertyTypeByColumnName(pk);
325 14 names.Add(pt.PropertyName);
326   }
327 14 if(beanMetaData.HasVersionNoPropertyType)
328 0 names.Add(beanMetaData.VersionNoPropertyName);
329 14 if(beanMetaData.HasTimestampPropertyType)
330 0 names.Add(beanMetaData.TimestampPropertyName);
331   }
332   }
333 68 if(names.Count == 0)
334   {
335 287 for(int i = 0; i < beanMetaData.PropertyTypeSize; ++i)
336   {
337 247 IPropertyType pt = beanMetaData.GetPropertyType(i);
338 247 if(pt.IsPersistent) names.Add(pt.PropertyName);
339   }
340   }
341 68 return (string[]) names.ToArray(typeof(string));
342   }
343  
344 84 protected bool IsPropertyExist(string[] props, string propertyName)
345   {
346 84 foreach(string prop in props)
347   {
348 84 if(string.Compare(prop, propertyName, true) == 0)
349 0 return true;
350   }
351 84 return false;
352   }
353  
354 38 protected void SetupSelectMethodByAuto(MethodInfo mi)
355   {
356 38 string query = annotationReader.GetQuery(mi.Name);
357 38 IDataReaderHandler handler = CreateDataReaderHandler(mi);
358 38 SelectDynamicCommand cmd = null;
359 38 string[] argNames = MethodUtil.GetParameterNames(mi);
360 38 Type[] argTypes = MethodUtil.GetParameterTypes(mi);
361 38 if(query != null && !StartsWithOrderBy(query))
362 33 cmd = CreateSelectDynamicCommand(handler, query);
363   else
364   {
365 5 cmd = CreateSelectDynamicCommand(handler);
366 5 string sql = null;
367  
368 5 if(argTypes.Length == 1 && (argTypes[0].IsPrimitive ||
369   argTypes[0].Equals(typeof(decimal)) || argTypes[0].Equals(typeof(DateTime))
370   || argTypes[0].Equals(typeof(string))))
371   {
372 0 argNames = new string[] { "dto" };
373 0 sql = CreateAutoSelectSqlByDto(argTypes[0]);
374   }
375   else
376 5 sql = CreateAutoSelectSql(argNames);
377 0 if(query != null) sql += " " + query;
378 5 cmd.Sql = sql;
379   }
380 38 cmd.ArgNames = argNames;
381 38 cmd.ArgTypes = argTypes;
382 38 sqlCommands[mi.Name] = cmd;
383   }
384  
385 0 protected string CreateAutoSelectSqlByDto(Type dtoType)
386   {
387   string sql = dbms.GetAutoSelectSql(BeanMetaData);
388   StringBuilder buf = new StringBuilder(sql);
389   IDtoMetaData dmd = new DtoMetaDataImpl(dtoType);
390   bool began = false;
391   if(!(sql.LastIndexOf("WHERE") > 0))
392   {
393   buf.Append("/*BEGIN*/ WHERE ");
394   began = true;
395   }
396   for(int i = 0; i < dmd.PropertyTypeSize; ++i)
397   {
398   IPropertyType pt = dmd.GetPropertyType(i);
399   string aliasName = pt.ColumnName;
400   if(!beanMetaData.HasPropertyTypeByAliasName(aliasName))
401   continue;
402   if(!beanMetaData.GetPropertyTypeByAliasName(aliasName).IsPersistent)
403   continue;
404   string columnName = beanMetaData.ConvertFullColumnName(aliasName);
405   string propertyName = "dto." + pt.PropertyName;
406   buf.Append("/*IF ");
407   buf.Append(propertyName);
408   buf.Append(" != null*/");
409   buf.Append(" ");
410   if(!began || i != 0) buf.Append("AND ");
411   buf.Append(columnName);
412   buf.Append(" = /*");
413   buf.Append(propertyName);
414   buf.Append("*/null");
415   buf.Append("/*END*/");
416   }
417   if(began) buf.Append("/*END*/");
418   return buf.ToString();
419   }
420  
421 5 protected string CreateAutoSelectSql(string[] argNames)
422   {
423 5 string sql = dbms.GetAutoSelectSql(BeanMetaData);
424 5 StringBuilder buf = new StringBuilder(sql);
425 5 if(argNames.Length != 0)
426   {
427 0 bool began = false;
428 0 if(!(sql.LastIndexOf("WHERE") > 0))
429   {
430   buf.Append("/*BEGIN*/ WHERE ");
431   began = true;
432   }
433 0 for(int i = 0; i < argNames.Length; ++i)
434   {
435   string columnName = beanMetaData.ConvertFullColumnName(argNames[i]);
436   buf.Append("/*IF ");
437   buf.Append(argNames[i]);
438   buf.Append(" != null*/");
439   buf.Append(" ");
440   if(!began || i != 0) buf.Append("AND ");
441   buf.Append(columnName);
442   buf.Append(" = /*");
443   buf.Append(argNames[i]);
444   buf.Append("*/null");
445   buf.Append("/*END*/");
446   }
447 0 if(began) buf.Append("/*END*/");
448   }
449 5 return buf.ToString();
450   }
451  
452 68 protected void CheckAutoUpdateMethod(MethodInfo mi)
453   {
454 68 Type[] parameterTypes = MethodUtil.GetParameterTypes(mi);
455 68 if(parameterTypes.Length != 1
456   || !IsBeanTypeAssignable(parameterTypes[0])
457   && !parameterTypes[0].IsAssignableFrom(typeof(IList))
458   && !parameterTypes[0].IsArray)
459   {
460 0 throw new IllegalSignatureRuntimeException("EDAO0006", mi.ToString());
461   }
462   }
463  
464 10 protected bool IsSelect(MethodInfo mi)
465   {
466 10 if(IsInsert(mi.Name)) return false;
467 0 if(IsUpdate(mi.Name)) return false;
468 0 if(IsDelete(mi.Name)) return false;
469 5 return true;
470   }
471  
472 116 protected bool IsInsert(string methodName)
473   {
474 116 foreach(string insertName in INSERT_NAMES)
475   {
476 284 if(methodName.StartsWith(insertName)) return true;
477   }
478 84 return false;
479   }
480  
481 84 protected bool IsUpdate(string methodName)
482   {
483 84 foreach(string updateName in UPDATE_NAMES)
484   {
485 192 if(methodName.StartsWith(updateName)) return true;
486   }
487 54 return false;
488   }
489  
490 54 protected bool IsDelete(string methodName)
491   {
492 54 foreach(string deleteName in DELETE_NAMES)
493   {
494 97 if(methodName.StartsWith(deleteName)) return true;
495   }
496 43 return false;
497   }
498  
499   #region IDaoMetaData メンバ
500  
501 0 public Type BeanType
502   {
503   get
504   {
505   return beanType;
506   }
507   }
508  
509   public IBeanMetaData BeanMetaData
510   {
511 38 get
512   {
513 38 return beanMetaData;
514   }
515   }
516  
517 0 public bool HasSqlCommand(string methodName)
518   {
519   return sqlCommands.Contains(methodName);
520   }
521  
522 21 public ISqlCommand GetSqlCommand(string methodName)
523   {
524 21 ISqlCommand cmd = (ISqlCommand) sqlCommands[methodName];
525 21 if(cmd == null)
526 0 throw new MethodNotFoundRuntimeException(daoType,
527   methodName, null);
528 21 return cmd;
529   }
530  
531 0 public ISqlCommand CreateFindCommand(string query)
532   {
533   return CreateSelectDynamicCommand(new BeanListMetaDataDataReaderHandler(
534   beanMetaData), query);
535   }
536  
537 0 public ISqlCommand CreateFindArrayCommand(string query)
538   {
539   return CreateSelectDynamicCommand(new BeanArrayMetaDataDataReaderHandler(
540   beanMetaData), query);
541   }
542  
543 0 public ISqlCommand CreateFindBeanCommand(string query)
544   {
545   return CreateSelectDynamicCommand(new BeanMetaDataDataReaderHandler(
546   beanMetaData), query);
547   }
548  
549 0 public ISqlCommand CreateFindObjectCommand(string query)
550   {
551   return CreateSelectDynamicCommand(new ObjectDataReaderHandler(), query);
552   }
553  
554   #endregion
555  
556 18 public static Type GetDaoInterface(Type type)
557   {
558 18 if(type.IsInterface) return type;
559 0 throw new DaoNotFoundRuntimeException(type);
560   }
561  
562 0 public IDbms Dbms
563   {
564   set { dbms = value; }
565   }
566   }
567   }
568