PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Kailua/net/windward/utils/ado/Oracle/WrOracleVendor.cs

#
C# | 327 lines | 242 code | 17 blank | 68 comment | 12 complexity | 06c251a831971ed08d16341ac523177e MD5 | raw file
  1. // Created by Windward Studios - no copyright is claimed. This code can be used in
  2. // any manner by anyone for any reason. There is no copyright of any kind on it. You may
  3. // use it in commercial products. You may change it without sharing those changes.
  4. // We ask that you keep the "created by Windward Studios" in a comment at the top.
  5. using System.Collections;
  6. using System.Data;
  7. using System.Data.Common;
  8. using System.Diagnostics;
  9. using System.IO;
  10. using Kailua.net.windward.utils;
  11. using Microsoft.Win32;
  12. // bugbug
  13. // 1: implement get stored procedures
  14. // 3: get schema owner for tables, views, stored procedures
  15. // 3: unit test both MS and Oracle connectors
  16. // 4: get table/view/stored procedure/column descriptions.
  17. // 4: get stored procedures variables (type & description)
  18. // this may help - http://msdn.microsoft.com/en-us/library/ms254969(VS.80).aspx
  19. namespace net.windward.utils.ado.Oracle
  20. {
  21. /// <summary>
  22. /// This is similiar to DbProviderFactory and provides additional functionality for each provider. All properties to list
  23. /// if a provider can perform any task in it's child classes is provider here, not in the child classes. This
  24. /// class can return IWrServer objects for a given server/instance that exists on a computer. The ODBC/OleDb
  25. /// concept of a Provider (which is different from a DbProviderFactory) is handled as a property set in the
  26. /// WrProviderFactory class so all other cases do not need to implement a class for that layer.
  27. /// This is called WrVendor instead of WrProvider because it is different from DbProviderFactory and because
  28. /// we use the term Provider for the ODBC/OleDb providers.
  29. /// This is the implementation for the Oracle databases.
  30. /// </summary>
  31. public class WrOracleVendor : WrVendor
  32. {
  33. /// <summary>
  34. /// The DbProviderFactory class for this vendor
  35. /// </summary>
  36. public const string FactoryClass = "Oracle.DataAccess.Client";
  37. /// <summary>
  38. /// The .NET Oracle class. Use is not recomended.
  39. /// </summary>
  40. public const string FactoryClassFramework = "System.Data.OracleClient";
  41. /// <summary>
  42. /// The suggested name for this vendor.
  43. /// </summary>
  44. public const string FactoryName = "Oracle";
  45. /// <summary>
  46. /// Creates an Oracle vendor object.
  47. /// </summary>
  48. public WrOracleVendor()
  49. : base(FactoryName, "The standard MS .NET Oracle connector", FactoryClass)
  50. {
  51. syntax = new WrOracleSyntax(providerFactory);
  52. }
  53. /// <summary>
  54. /// Creates an ODBC vendor object.
  55. /// </summary>
  56. /// <param name="name">The friendly name of the provider.</param>
  57. /// <param name="description">The description of this provider (optional).</param>
  58. /// <param name="providerClass">The class of the provider.</param>
  59. public WrOracleVendor(string name, string description, string providerClass)
  60. : base(name, description, providerClass)
  61. {
  62. syntax = new WrOracleSyntax(providerFactory);
  63. }
  64. #region WrVendor properties
  65. /// <summary>
  66. /// True if can enumerate running servers from this vendor. This is implemented seperately from
  67. /// CanCreateDataSourceEnumerator because DB2 and SqlServer implement CreateDataSourceEnumerator differently.
  68. /// </summary>
  69. public override bool CanEnumerateServers
  70. {
  71. get
  72. {
  73. // first we try the provider
  74. if ((providerFactory != null) && providerFactory.CanCreateDataSourceEnumerator)
  75. {
  76. DbDataSourceEnumerator dsEnum = providerFactory.CreateDataSourceEnumerator();
  77. if (dsEnum != null)
  78. {
  79. DataTable servers = dsEnum.GetDataSources();
  80. if (servers.Rows.Count > 0)
  81. {
  82. Trap.trap();
  83. return true;
  84. }
  85. }
  86. }
  87. // now we do it the hard way
  88. TNSParser.TNSEntry[] entries = TNSParser.GetAllEntries();
  89. return entries.Length > 0;
  90. }
  91. }
  92. /// <summary>
  93. /// True if can enumerate databases on a server. This is implemented seperately from
  94. /// CanCreateDataSourceEnumerator because DB2 and SqlServer implement CreateDataSourceEnumerator differently.
  95. /// </summary>
  96. public override bool CanEnumerateDatabases
  97. {
  98. get { return false; }
  99. }
  100. /// <summary>
  101. /// True if can query metadata from the database.
  102. /// </summary>
  103. public override bool CanQueryMetadata
  104. {
  105. get { return true; }
  106. }
  107. /// <summary>
  108. /// True if can launch the administrator for this vendor. This will return true if it can find the admin
  109. /// program file. In that case the launch could still fail.
  110. /// </summary>
  111. public override bool CanLaunchAdministrator
  112. {
  113. get
  114. {
  115. return GetAdminFilename() != null;
  116. }
  117. }
  118. /// <summary>
  119. /// True if can run DDL scripts.
  120. /// </summary>
  121. public override bool CanRunScripts
  122. {
  123. get { return false; }
  124. }
  125. /// <summary>
  126. /// True if can use the WindowsIdentity of the caller eliminating the need to pass a username and password.
  127. /// </summary>
  128. public override bool CanUseTrustedConnection
  129. {
  130. get { return false; }
  131. }
  132. /// <summary>
  133. /// All servers from this vendor on the network. This may not get all due to routers not passing
  134. /// on a broadcast or delays in some servers responding.
  135. /// </summary>
  136. /// <exception cref="WrDbException">Thrown if this provider does not support enumerate servers.</exception>
  137. /// <returns>All servers found on the sub-net.</returns>
  138. public override IWrServer[] GetServers()
  139. {
  140. ArrayList rtn = new ArrayList();
  141. DbDataSourceEnumerator dsEnum = providerFactory.CreateDataSourceEnumerator();
  142. if (dsEnum != null)
  143. {
  144. DataTable servers = dsEnum.GetDataSources();
  145. int ordServer = servers.Columns.IndexOf("ServerName");
  146. int ordInstance = servers.Columns.IndexOf("InstanceName");
  147. Trap.trap(servers.Rows.Count > 0);
  148. foreach (DataRow row in servers.Rows)
  149. {
  150. string server = (string) row[ordServer];
  151. string instance = (ordInstance == -1) || row.IsNull(ordInstance) ? null : (string) row[ordInstance];
  152. if (!string.IsNullOrEmpty(instance))
  153. server += "\\" + instance;
  154. rtn.Add(new WrOracleServer(providerFactory, server));
  155. }
  156. rtn.Sort();
  157. return (WrOracleServer[]) rtn.ToArray(typeof (WrOracleServer));
  158. }
  159. TNSParser.TNSEntry[] entries = TNSParser.GetAllEntries();
  160. foreach (TNSParser.TNSEntry entry in entries)
  161. rtn.Add(new WrOracleServer(providerFactory, entry.Name));
  162. rtn.Sort();
  163. return (WrOracleServer[])rtn.ToArray(typeof(WrOracleServer));
  164. }
  165. /// <summary>
  166. /// True if this vendor has the conecpt of multiple databases in an installed copy of their product. The only
  167. /// known case where this is false is Oracle.
  168. /// </summary>
  169. public override DATABASE_MODE DatabaseMode
  170. {
  171. get { return DATABASE_MODE.NEVER; }
  172. }
  173. /// <summary>
  174. /// Returns true if the Oracle client is installed on this system (required for OracleConnection to work).
  175. /// </summary>
  176. public override bool IsInstalled
  177. {
  178. get
  179. {
  180. return providerFactory != null;
  181. }
  182. }
  183. #endregion
  184. #region WrVendor methods
  185. /// <summary>
  186. /// A connection string for a database on a server.
  187. /// </summary>
  188. /// <param name="server">The server to access (ex: localhost).</param>
  189. /// <param name="database">The database to connect to.</param>
  190. /// <param name="credentials">The user credentials to access the database.</param>
  191. /// <param name="showPassword">True to include the password, false to add the password as *****.</param>
  192. /// <returns>The connection string for this database on this server.</returns>
  193. public override string ConnectionString(string server, string database, WrCredentials credentials, bool showPassword)
  194. {
  195. return ConnectionString(providerFactory, server, database, credentials, showPassword);
  196. }
  197. internal static string ConnectionString(DbProviderFactory provider, string server, string database, WrCredentials credentials, bool showPassword)
  198. {
  199. DbConnectionStringBuilder connStrBuilder = provider.CreateConnectionStringBuilder();
  200. if (!string.IsNullOrEmpty(server))
  201. connStrBuilder.Add("Data Source", server);
  202. connStrBuilder.Add("Persist Security Info", "True");
  203. if (!credentials.UseWindowsIdentity)
  204. {
  205. if (!string.IsNullOrEmpty(credentials.Username))
  206. connStrBuilder.Add("User ID", credentials.Username);
  207. if (!string.IsNullOrEmpty(credentials.Password))
  208. connStrBuilder.Add("Password", showPassword ? credentials.Password : "*****");
  209. }
  210. return connStrBuilder.ConnectionString;
  211. }
  212. /// <summary>
  213. /// Returns the parameters from a connection string making the best guess. Will return null for items it could not determine.
  214. /// </summary>
  215. /// <param name="connectionString">The connection string to parse.</param>
  216. /// <returns>The parameters.</returns>
  217. public override WrConnectionParams ConnectionParams(string connectionString)
  218. {
  219. if (string.IsNullOrEmpty(connectionString))
  220. return new WrConnectionParams();
  221. Trap.trap();
  222. System.Data.Common.DbConnectionStringBuilder builder = providerFactory.CreateConnectionStringBuilder();
  223. Trap.trap(builder.GetType().FullName.StartsWith("System.Data.OracleClient."));
  224. Trap.trap(! builder.GetType().FullName.StartsWith("System.Data.OracleClient."));
  225. builder.ConnectionString = connectionString;
  226. return new WrConnectionParams(builder["server"] as string, null, builder["user id"] as string, builder["password"] as string);
  227. }
  228. /// <summary>
  229. /// Returns a new instance of the provider's class that implements the WrCommand class.
  230. /// </summary>
  231. /// <returns>A new instance of WrCommand.</returns>
  232. public override WrCommand CreateCommand()
  233. {
  234. Trap.trap();
  235. return new WrOracleCommand(providerFactory);
  236. }
  237. /// <summary>
  238. /// Create a server object.
  239. /// </summary>
  240. /// <param name="server">The name of the server the database is on.</param>
  241. public override IWrServer CreateServer(string server)
  242. {
  243. return new WrOracleServer(providerFactory, server);
  244. }
  245. /// <summary>
  246. /// Launch the database admin tool.
  247. /// </summary>
  248. /// <returns>True if launched successfully.</returns>
  249. public override bool RunAdministrator()
  250. {
  251. Process proc = Process.Start(GetAdminFilename());
  252. return (proc != null) && (!proc.HasExited);
  253. }
  254. private static readonly string[] keys = { "SOFTWARE\\ORACLE\\KEY_OraClient10g_home1",
  255. "SOFTWARE\\ORACLE\\KEY_OraClient10g_home2",
  256. "SOFTWARE\\ORACLE\\KEY_OraClient10g_home3",
  257. "SOFTWARE\\ORACLE\\KEY_OraClient10g_home4",
  258. "SOFTWARE\\ORACLE\\KEY_OraClient10g_home5",
  259. "SOFTWARE\\ORACLE\\KEY_OraClient10g_home6",
  260. "SOFTWARE\\ORACLE\\KEY_OraClient10g_home7",
  261. "SOFTWARE\\ORACLE\\KEY_XE"};
  262. private static string GetAdminFilename()
  263. {
  264. foreach (string key in keys)
  265. {
  266. string exe = GetExe(key);
  267. if (exe != null)
  268. {
  269. string file = Path.Combine(exe, "BIN\\oemapp.bat");
  270. if (File.Exists(file))
  271. return file;
  272. file = Path.Combine(exe, "Database_homepage.url");
  273. if (File.Exists(file))
  274. return file;
  275. }
  276. }
  277. return null;
  278. }
  279. private static string GetExe(string path)
  280. {
  281. RegistryKey key = Registry.LocalMachine.OpenSubKey(path);
  282. if (key == null)
  283. return null;
  284. string exe = (string)key.GetValue("ORACLE_HOME");
  285. if (exe == null)
  286. return null;
  287. key.Close();
  288. return exe;
  289. }
  290. #endregion
  291. }
  292. }