PageRenderTime 45ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/System.Data.Linq/src/DbLinq.Ingres/IngresVendor.cs

https://bitbucket.org/danipen/mono
C# | 248 lines | 168 code | 24 blank | 56 comment | 17 complexity | 920b2f57afc970dfc971b724ae06a87e MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. #region MIT license
  2. //
  3. // MIT license
  4. //
  5. // Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining a copy
  8. // of this software and associated documentation files (the "Software"), to deal
  9. // in the Software without restriction, including without limitation the rights
  10. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the Software is
  12. // furnished to do so, subject to the following conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be included in
  15. // all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. // THE SOFTWARE.
  24. //
  25. #endregion
  26. using System;
  27. using System.Data;
  28. using System.Linq;
  29. using System.Data.Linq.Mapping;
  30. using System.Reflection;
  31. using System.Collections.Generic;
  32. using System.Text;
  33. using DbLinq.Data.Linq.SqlClient;
  34. using DbLinq.Util;
  35. using DbLinq.Vendor;
  36. #if MONO_STRICT
  37. using DataContext = System.Data.Linq.DataContext;
  38. #else
  39. using DataContext = DbLinq.Data.Linq.DataContext;
  40. #endif
  41. namespace DbLinq.Ingres
  42. {
  43. /// <summary>
  44. /// Ingres - specific code.
  45. /// </summary>
  46. [Vendor(typeof(IngresProvider))]
  47. #if !MONO_STRICT
  48. public
  49. #endif
  50. class IngresVendor : Vendor.Implementation.Vendor
  51. {
  52. public override string VendorName { get { return "Ingres"; } }
  53. protected readonly IngresSqlProvider sqlProvider = new IngresSqlProvider();
  54. public override ISqlProvider SqlProvider { get { return sqlProvider; } }
  55. //private string lastIdExpression = null;
  56. private bool isReplaceable(IDbDataParameter param)
  57. {
  58. switch (param.DbType)
  59. {
  60. case DbType.String:
  61. case DbType.Int16:
  62. case DbType.Int32:
  63. case DbType.Int64:
  64. case DbType.Double:
  65. return true;
  66. }
  67. return false;
  68. }
  69. private string getParamValueAsString(IDbDataParameter param)
  70. {
  71. switch (param.DbType)
  72. {
  73. case DbType.String:
  74. return " '" + param.Value.ToString() + "' ";
  75. case DbType.Int16:
  76. case DbType.Int32:
  77. case DbType.Int64:
  78. case DbType.Double:
  79. return param.Value.ToString();
  80. }
  81. throw new Exception("Not prepared to convert " + param.DbType.ToString());
  82. }
  83. protected void SetParameterType(IDbDataParameter parameter, PropertyInfo property, string literal)
  84. {
  85. object dbType = Enum.Parse(property.PropertyType, literal);
  86. property.GetSetMethod().Invoke(parameter, new object[] { dbType });
  87. }
  88. protected void SetParameterType(IDbDataParameter parameter, string literal)
  89. {
  90. SetParameterType(parameter, parameter.GetType().GetProperty("IngresDbType"), literal);
  91. }
  92. /// <summary>
  93. /// call mysql stored proc or stored function,
  94. /// optionally return DataSet, and collect return params.
  95. /// </summary>
  96. public override System.Data.Linq.IExecuteResult ExecuteMethodCall(DataContext context, MethodInfo method
  97. , params object[] inputValues)
  98. {
  99. if (method == null)
  100. throw new ArgumentNullException("L56 Null 'method' parameter");
  101. //check to make sure there is exactly one [FunctionEx]? that's below.
  102. //FunctionAttribute functionAttrib = GetFunctionAttribute(method);
  103. var functionAttrib = context.Mapping.GetFunction(method);
  104. ParameterInfo[] paramInfos = method.GetParameters();
  105. //int numRequiredParams = paramInfos.Count(p => p.IsIn || p.IsRetval);
  106. //if (numRequiredParams != inputValues.Length)
  107. // throw new ArgumentException("L161 Argument count mismatch");
  108. string sp_name = functionAttrib.MappedName;
  109. using (IDbCommand command = context.Connection.CreateCommand())
  110. {
  111. command.CommandText = sp_name;
  112. //MySqlCommand command = new MySqlCommand("select hello0()");
  113. int currInputIndex = 0;
  114. List<string> paramNames = new List<string>();
  115. for (int i = 0; i < paramInfos.Length; i++)
  116. {
  117. ParameterInfo paramInfo = paramInfos[i];
  118. //TODO: check to make sure there is exactly one [Parameter]?
  119. ParameterAttribute paramAttrib = paramInfo.GetCustomAttributes(false).OfType<ParameterAttribute>().Single();
  120. //string paramName = "?" + paramAttrib.Name; //eg. '?param1' MYSQL
  121. string paramName = ":" + paramAttrib.Name; //eg. '?param1' PostgreSQL
  122. paramNames.Add(paramName);
  123. System.Data.ParameterDirection direction = GetDirection(paramInfo, paramAttrib);
  124. //MySqlDbType dbType = MySqlTypeConversions.ParseType(paramAttrib.DbType);
  125. IDbDataParameter cmdParam = command.CreateParameter();
  126. cmdParam.ParameterName = paramName;
  127. //cmdParam.Direction = System.Data.ParameterDirection.Input;
  128. if (direction == ParameterDirection.Input || direction == ParameterDirection.InputOutput)
  129. {
  130. object inputValue = inputValues[currInputIndex++];
  131. cmdParam.Value = inputValue;
  132. }
  133. else
  134. {
  135. cmdParam.Value = null;
  136. }
  137. cmdParam.Direction = direction;
  138. command.Parameters.Add(cmdParam);
  139. }
  140. if (!functionAttrib.IsComposable)
  141. {
  142. //procedures: under the hood, this seems to prepend 'CALL '
  143. command.CommandType = System.Data.CommandType.StoredProcedure;
  144. }
  145. else
  146. {
  147. //functions: 'SELECT myFunction()' or 'SELECT hello(?s)'
  148. string cmdText = "SELECT " + command.CommandText + "($args)";
  149. cmdText = cmdText.Replace("$args", string.Join(",", paramNames.ToArray()));
  150. command.CommandText = cmdText;
  151. }
  152. if (method.ReturnType == typeof(DataSet))
  153. {
  154. //unknown shape of resultset:
  155. System.Data.DataSet dataSet = new DataSet();
  156. IDbDataAdapter adapter = CreateDataAdapter(context);
  157. adapter.SelectCommand = command;
  158. adapter.Fill(dataSet);
  159. List<object> outParamValues = CopyOutParams(paramInfos, command.Parameters);
  160. return new ProcedureResult(dataSet, outParamValues.ToArray());
  161. }
  162. else
  163. {
  164. object obj = command.ExecuteScalar();
  165. List<object> outParamValues = CopyOutParams(paramInfos, command.Parameters);
  166. return new ProcedureResult(obj, outParamValues.ToArray());
  167. }
  168. }
  169. }
  170. static ParameterDirection GetDirection(ParameterInfo paramInfo, ParameterAttribute paramAttrib)
  171. {
  172. //strange hack to determine what's a ref, out parameter:
  173. //http://lists.ximian.com/pipermain/mono-list/2003-March/012751.html
  174. bool hasAmpersand = paramInfo.ParameterType.FullName.Contains('&');
  175. if (paramInfo.IsOut)
  176. return ParameterDirection.Output;
  177. if (hasAmpersand)
  178. return ParameterDirection.InputOutput;
  179. return ParameterDirection.Input;
  180. }
  181. /// <summary>
  182. /// Collect all Out or InOut param values, casting them to the correct .net type.
  183. /// </summary>
  184. static List<object> CopyOutParams(ParameterInfo[] paramInfos, IDataParameterCollection paramSet)
  185. {
  186. List<object> outParamValues = new List<object>();
  187. //Type type_t = typeof(T);
  188. int i = -1;
  189. foreach (IDbDataParameter param in paramSet)
  190. {
  191. i++;
  192. if (param.Direction == ParameterDirection.Input)
  193. {
  194. outParamValues.Add("unused");
  195. continue;
  196. }
  197. object val = param.Value;
  198. Type desired_type = paramInfos[i].ParameterType;
  199. if (desired_type.Name.EndsWith("&"))
  200. {
  201. //for ref and out parameters, we need to tweak ref types, e.g.
  202. // "System.Int32&, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  203. string fullName1 = desired_type.AssemblyQualifiedName;
  204. string fullName2 = fullName1.Replace("&", "");
  205. desired_type = Type.GetType(fullName2);
  206. }
  207. try
  208. {
  209. //fi.SetValue(t, val); //fails with 'System.Decimal cannot be converted to Int32'
  210. //DbLinq.util.FieldUtils.SetObjectIdField(t, fi, val);
  211. //object val2 = DbLinq.Util.FieldUtils.CastValue(val, desired_type);
  212. object val2 = TypeConvert.To(val, desired_type);
  213. outParamValues.Add(val2);
  214. }
  215. catch (Exception ex)
  216. {
  217. //fails with 'System.Decimal cannot be converted to Int32'
  218. Console.WriteLine("CopyOutParams ERROR L245: failed on CastValue(): " + ex.Message);
  219. }
  220. }
  221. return outParamValues;
  222. }
  223. }
  224. }