Clover.NET coverage report - Coverage for s2dao.net

Coverage timestamp: 2006年5月30日 11:48:56

File Stats: LOC: 568   Methods: 37
NCLOC: 492 Classes: 1
 
Source File Conditionals Statements Methods TOTAL
Seasar.Dao.Impl\DaoMetaDataImpl.cs 65.8% 75.7% 78.4% 73.1%
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 24 public DaoMetaDataImpl(Type daoType, IDataSource dataSource,ICommandFactory commandFactory,
62   IDataReaderFactory dataReaderFactory, IDatabaseMetaData dbMetaData)
63   {
64 24 this.daoType = daoType;
65 24 daoInterface = GetDaoInterface(daoType);
66 24 annotationReader = new FieldAnnotationReader(daoType);
67 24 beanType = annotationReader.GetBeanType();
68 24 this.dataSource = dataSource;
69  
70 24 this.commandFactory = commandFactory;
71 24 this.dataReaderFactory = dataReaderFactory;
72 24 dbms = DbmsManager.GetDbms(dataSource);
73 24 beanMetaData = new BeanMetaDataImpl(beanType, dbMetaData, dbms);
74 24 SetupSqlCommand();
75   }
76  
77 24 protected void SetupSqlCommand()
78   {
79 24 MethodInfo[] allMethods = daoInterface.GetMethods();
80 24 Hashtable names = new Hashtable();
81 24 foreach(MethodInfo mi in allMethods)
82   {
83 159 names[mi.Name] = mi;
84   }
85 24 IDictionaryEnumerator enu = names.GetEnumerator();
86 183 while(enu.MoveNext())
87   {
88 159 try
89   {
90 159 MethodInfo method = daoType.GetMethod((string) enu.Key);
91 159 if(method.IsAbstract) SetupMethod(method);
92   }
93   catch(AmbiguousMatchException) {}
94   }
95   }
96  
97 159 protected void SetupMethod(MethodInfo mi)
98   {
99 159 string sql = null;
100 159 sql = annotationReader.GetSql(mi.Name, dbms);
101 159 if(sql != null)
102   {
103 28 SetupMethodByManual(mi, sql);
104 28 return;
105   }
106 131 string baseName = daoInterface.FullName + "_" + mi.Name;
107 131 string dbmsPath = baseName + dbms.Suffix + ".sql";
108 131 string standardPath = baseName + ".sql";
109 131 Assembly asm = daoInterface.Assembly;
110  
111 131 if(ResourceUtil.IsExist(dbmsPath, asm))
112   {
113 0 sql = TextUtil.ReadText(dbmsPath, asm);
114 0 SetupMethodByManual(mi, sql);
115   }
116 131 else if(ResourceUtil.IsExist(standardPath, asm))
117   {
118 7 sql = TextUtil.ReadText(standardPath, asm);
119 7 SetupMethodByManual(mi, sql);
120   }
121   else
122   {
123 124 SetupMethodByAuto(mi);
124   }
125   }
126  
127 35 protected void SetupMethodByManual(MethodInfo mi, string sql)
128   {
129 35 if(IsSelect(mi))
130   {
131 28 SetupSelectMethodByManual(mi, sql);
132   }
133   else
134   {
135 7 SetupUpdateMethodByManual(mi, sql);
136   }
137   }
138  
139 124 protected void SetupMethodByAuto(MethodInfo mi)
140   {
141 124 if(IsInsert(mi.Name))
142   {
143 31 SetupInsertMethodByAuto(mi);
144   }
145 93 else if(IsUpdate(mi.Name))
146   {
147 32 SetupUpdateMethodByAuto(mi);
148   }
149 61 else if(IsDelete(mi.Name))
150   {
151 11 SetupDeleteMethodByAuto(mi);
152   }
153   else
154   {
155 50 SetupSelectMethodByAuto(mi);
156   }
157   }
158  
159 28 protected void SetupSelectMethodByManual(MethodInfo mi, string sql)
160   {
161 28 SelectDynamicCommand cmd = CreateSelectDynamicCommand(CreateDataReaderHandler(mi));
162 28 cmd.Sql = sql;
163 28 cmd.ArgNames = MethodUtil.GetParameterNames(mi);
164 28 cmd.ArgTypes = MethodUtil.GetParameterTypes(mi);
165 28 sqlCommands[mi.Name] = cmd;
166   }
167  
168 78 protected SelectDynamicCommand CreateSelectDynamicCommand(IDataReaderHandler drh)
169   {
170 78 return new SelectDynamicCommand(dataSource, commandFactory, drh, dataReaderFactory);
171   }
172  
173 39 protected SelectDynamicCommand CreateSelectDynamicCommand(
174   IDataReaderHandler dataReaderHandler, string query)
175   {
176 39 SelectDynamicCommand cmd = CreateSelectDynamicCommand(dataReaderHandler);
177 39 StringBuilder buf = new StringBuilder(255);
178 39 if(StartsWithSelect(query))
179 0 buf.Append(query);
180   else
181   {
182 39 string sql = dbms.GetAutoSelectSql(BeanMetaData);
183 39 buf.Append(sql);
184 39 if(query != null)
185   {
186 39 if(StartsWithOrderBy(query))
187 0 buf.Append(" ");
188 39 else if(sql.LastIndexOf("WHERE") < 0)
189 39 buf.Append(" WHERE ");
190   else
191 0 buf.Append(" AND ");
192 39 buf.Append(query);
193   }
194   }
195 39 cmd.Sql = buf.ToString();
196 39 return cmd;
197   }
198  
199 39 protected static bool StartsWithSelect(string query)
200   {
201 39 return StringUtil.StartWith(query, "select");
202   }
203  
204 78 protected static bool StartsWithOrderBy(string query)
205   {
206 78 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 78 return false;
213   }
214  
215 78 protected IDataReaderHandler CreateDataReaderHandler(MethodInfo mi)
216   {
217 78 if (mi.ReturnType.IsArray)
218 0 return new BeanArrayMetaDataDataReaderHandler(beanMetaData);
219 78 else if(typeof(IList).IsAssignableFrom(mi.ReturnType))
220 32 return new BeanListMetaDataDataReaderHandler(beanMetaData);
221 46 else if(IsBeanTypeAssignable(mi.ReturnType))
222 18 return new BeanMetaDataDataReaderHandler(beanMetaData);
223 28 else if(Array.CreateInstance(beanType, 0).GetType()
224   .IsAssignableFrom(mi.ReturnType))
225 0 return new BeanArrayMetaDataDataReaderHandler(beanMetaData);
226   else
227 28 return new ObjectDataReaderHandler();
228   }
229  
230 194 protected bool IsBeanTypeAssignable(Type type)
231   {
232 194 return beanType.IsAssignableFrom(type) ||
233   type.IsAssignableFrom(beanType);
234   }
235  
236 7 protected void SetupUpdateMethodByManual(MethodInfo mi, string sql)
237   {
238 7 UpdateDynamicCommand cmd = new UpdateDynamicCommand(dataSource, commandFactory);
239 7 cmd.Sql = sql;
240 7 string[] argNames = MethodUtil.GetParameterNames(mi);
241 7 if(argNames.Length == 0 && IsUpdateSignatureForBean(mi))
242 0 argNames = new string[] { StringUtil.Decapitalize(beanType.Name) };
243 7 cmd.ArgNames = argNames;
244 7 cmd.ArgTypes = MethodUtil.GetParameterTypes(mi);
245   // cmd.NotSingleRowUpdatedExceptionType = GetNotSingleRowUpdatedExceptionType(mi);
246 7 sqlCommands[mi.Name] = cmd;
247   }
248  
249 74 protected bool IsUpdateSignatureForBean(MethodInfo mi)
250   {
251 74 Type[] paramTypes = MethodUtil.GetParameterTypes(mi);
252 74 return paramTypes.Length == 1
253   && IsBeanTypeAssignable(paramTypes[0]);
254   }
255  
256   // protected Type GetNotSingleRowUpdatedExceptionType(MethodInfo mi)
257   // {
258   // }
259  
260 31 protected void SetupInsertMethodByAuto(MethodInfo mi)
261   {
262 31 CheckAutoUpdateMethod(mi);
263 31 string[] propertyNames = GetPersistentPropertyNames(mi.Name);
264 31 ISqlCommand cmd = null;
265 31 if(IsUpdateSignatureForBean(mi))
266 31 cmd = new InsertAutoStaticCommand(dataSource, commandFactory,
267   beanMetaData, propertyNames);
268   else
269 0 throw new NotSupportedException("InsertBatchAutoStaticCommand");
270 31 sqlCommands[mi.Name] = cmd;
271   }
272  
273 32 protected void SetupUpdateMethodByAuto(MethodInfo mi)
274   {
275 32 CheckAutoUpdateMethod(mi);
276 32 string[] propertyNames = GetPersistentPropertyNames(mi.Name);
277 32 AbstractSqlCommand cmd = null;
278 32 if(IsUpdateSignatureForBean(mi))
279 32 cmd = new UpdateAutoStaticCommand(dataSource, commandFactory,
280   beanMetaData, propertyNames);
281   else
282 0 throw new NotSupportedException("UpdateBatchAutoStaticCommand");
283  
284 32 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 74 protected string[] GetPersistentPropertyNames(string methodName)
301   {
302 74 ArrayList names = new ArrayList();
303 74 string[] props = annotationReader.GetNoPersistentProps(methodName);
304 74 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 60 props = annotationReader.GetPersistentProps(methodName);
317 60 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 74 if(names.Count == 0)
334   {
335 311 for(int i = 0; i < beanMetaData.PropertyTypeSize; ++i)
336   {
337 265 IPropertyType pt = beanMetaData.GetPropertyType(i);
338 265 if(pt.IsPersistent) names.Add(pt.PropertyName);
339   }
340   }
341 74 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 50 protected void SetupSelectMethodByAuto(MethodInfo mi)
355   {
356 50 string query = annotationReader.GetQuery(mi.Name);
357 50 IDataReaderHandler handler = CreateDataReaderHandler(mi);
358 50 SelectDynamicCommand cmd = null;
359 50 string[] argNames = MethodUtil.GetParameterNames(mi);
360 50 Type[] argTypes = MethodUtil.GetParameterTypes(mi);
361 50 if(query != null && !StartsWithOrderBy(query))
362 39 cmd = CreateSelectDynamicCommand(handler, query);
363   else
364   {
365 11 cmd = CreateSelectDynamicCommand(handler);
366 11 string sql = null;
367  
368 11 if(argNames.Length == 0 && mi.GetParameters().Length == 1)
369   {
370 0 argNames = new string[] { "dto" };
371 0 sql = CreateAutoSelectSqlByDto(argTypes[0]);
372   }
373   else
374   {
375 11 sql = CreateAutoSelectSql(argNames);
376   }
377 0 if(query != null) sql += " " + query;
378 11 cmd.Sql = sql;
379   }
380 50 cmd.ArgNames = argNames;
381 50 cmd.ArgTypes = argTypes;
382 50 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 11 protected string CreateAutoSelectSql(string[] argNames)
422   {
423 11 string sql = dbms.GetAutoSelectSql(BeanMetaData);
424 11 StringBuilder buf = new StringBuilder(sql);
425 11 if(argNames.Length != 0)
426   {
427 4 bool began = false;
428 4 if(!(sql.LastIndexOf("WHERE") > 0))
429   {
430 4 buf.Append("/*BEGIN*/ WHERE ");
431 4 began = true;
432   }
433 8 for(int i = 0; i < argNames.Length; ++i)
434   {
435 4 string columnName = beanMetaData.ConvertFullColumnName(argNames[i]);
436 4 buf.Append("/*IF ");
437 4 buf.Append(argNames[i]);
438 4 buf.Append(" != null*/");
439 4 buf.Append(" ");
440 0 if(!began || i != 0) buf.Append("AND ");
441 4 buf.Append(columnName);
442 4 buf.Append(" = /*");
443 4 buf.Append(argNames[i]);
444 4 buf.Append("*/null");
445 4 buf.Append("/*END*/");
446   }
447 4 if(began) buf.Append("/*END*/");
448   }
449 11 return buf.ToString();
450   }
451  
452 74 protected void CheckAutoUpdateMethod(MethodInfo mi)
453   {
454 74 Type[] parameterTypes = MethodUtil.GetParameterTypes(mi);
455 74 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 35 protected bool IsSelect(MethodInfo mi)
465   {
466 35 if(IsInsert(mi.Name)) return false;
467 0 if(IsUpdate(mi.Name)) return false;
468 0 if(IsDelete(mi.Name)) return false;
469 28 return true;
470   }
471  
472 159 protected bool IsInsert(string methodName)
473   {
474 159 foreach(string insertName in INSERT_NAMES)
475   {
476 401 if(methodName.StartsWith(insertName)) return true;
477   }
478 121 return false;
479   }
480  
481 121 protected bool IsUpdate(string methodName)
482   {
483 121 foreach(string updateName in UPDATE_NAMES)
484   {
485 299 if(methodName.StartsWith(updateName)) return true;
486   }
487 89 return false;
488   }
489  
490 89 protected bool IsDelete(string methodName)
491   {
492 89 foreach(string deleteName in DELETE_NAMES)
493   {
494 167 if(methodName.StartsWith(deleteName)) return true;
495   }
496 78 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 50 get
512   {
513 50 return beanMetaData;
514   }
515   }
516  
517 0 public bool HasSqlCommand(string methodName)
518   {
519   return sqlCommands.Contains(methodName);
520   }
521  
522 33 public ISqlCommand GetSqlCommand(string methodName)
523   {
524 33 ISqlCommand cmd = (ISqlCommand) sqlCommands[methodName];
525 33 if(cmd == null)
526 0 throw new MethodNotFoundRuntimeException(daoType,
527   methodName, null);
528 33 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 24 public static Type GetDaoInterface(Type type)
557   {
558 24 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