// Copyright © 2004, 2014, Oracle and/or its affiliates. All rights reserved. // // MySQL Connector/NET is licensed under the terms of the GPLv2 // , like most // MySQL Connectors. There are special exceptions to the terms and // conditions of the GPLv2 as it is applied to this software, see the // FLOSS License Exception // . // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published // by the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA using System; using System.Collections.Generic; using System.Configuration; using System.Configuration.Provider; using System.Data; using System.Diagnostics; using System.Text; using System.Web; using MySql.Data.MySqlClient; using MySql.Web.Common; using MySql.Web.Properties; namespace MySql.Web.SiteMap { /// /// SiteMap provider backed by MySql database. /// public class MySqlSiteMapProvider : StaticSiteMapProvider { private readonly object _lockObject = new object(); private string _connStr; private SiteMapNode _rootNode; private Dictionary _nodes = new Dictionary(); private bool writeExceptionsToEventLog; string eventSource = "MySQLSiteMap"; string eventLog = "Application"; string exceptionMessage = "An exception occurred. Please check the event log."; internal bool WriteExceptionsToEventLog { get { return writeExceptionsToEventLog; } } public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) { base.Initialize(name, config); if (config == null) throw new ArgumentException(Resources.SiteMapConnectionStringMissing); string connStrName; if (string.IsNullOrEmpty(connStrName = config["connectionStringName"])) throw new ArgumentException(Resources.SiteMapConnectionStringMissing); _connStr = ConfigurationManager.ConnectionStrings[connStrName].ConnectionString; writeExceptionsToEventLog = false; if (config["writeExceptionsToEventLog"] != null) { writeExceptionsToEventLog = (config["writeExceptionsToEventLog"].ToUpper() == "TRUE"); } SchemaManager.CheckSchema(_connStr, config); } public override SiteMapNode BuildSiteMap() { lock (_lockObject) { if (_rootNode != null) return _rootNode; string sql = "select Id, Title, Description, Url, Roles, ParentId from my_aspnet_sitemap"; MySqlConnection conn = new MySqlConnection(_connStr); try { conn.Open(); MySqlCommand cmd = new MySqlCommand(sql, conn); using (MySqlDataReader r = cmd.ExecuteReader()) { int IdFld = r.GetOrdinal("Id"); int TitleFld = r.GetOrdinal("Title"); int DescFld = r.GetOrdinal("Description"); int UrlFld = r.GetOrdinal("Url"); int RolesFld = r.GetOrdinal("Roles"); int ParentIdFld = r.GetOrdinal("ParentId"); while (r.Read()) { int IdVal; string TitleVal; string DescVal; string UrlVal; string RolesVal; int ParentIdVal; LoadValue(r, IdFld, out IdVal); LoadValue(r, TitleFld, out TitleVal); LoadValue(r, DescFld, out DescVal); LoadValue(r, UrlFld, out UrlVal); LoadValue(r, RolesFld, out RolesVal); LoadValue(r, ParentIdFld, out ParentIdVal); SiteMapNode node = new SiteMapNode(this, IdVal.ToString(), UrlVal, TitleVal, DescVal); _nodes.Add(IdVal, node); if (ParentIdVal != 0) { SiteMapNode parentNode = _nodes[ParentIdVal]; AddNode(node, parentNode); } else { AddNode(node); } if (ParentIdVal == 0) { _rootNode = node; } } } } catch (MySqlException ex) { HandleMySqlException(ex, "BuildSiteMap"); } finally { if ((conn.State & ConnectionState.Open) != 0) conn.Close(); } return _rootNode; } } private void LoadValue(MySqlDataReader r, int fldNum, out T val) { if (r.IsDBNull(fldNum)) val = default(T); else { val = (T)r.GetValue(fldNum); } } public override SiteMapNode FindSiteMapNodeFromKey(string key) { if (string.IsNullOrEmpty(key)) return null; else { int idKey = Convert.ToInt32(key); SiteMapNode node; _nodes.TryGetValue(idKey, out node); return node; } } /// /// Handles MySql exception. /// If WriteExceptionsToEventLog is set, will write exception info /// to event log. /// It throws provider exception (original exception is stored as inner exception) /// /// exception /// name of the function that throwed the exception private void HandleMySqlException(MySqlException e, string action) { if (WriteExceptionsToEventLog) { using (EventLog log = new EventLog()) { log.Source = eventSource; log.Log = eventLog; string message = "An exception occurred communicating with the data source.\n\n"; message += "Action: " + action; message += "Exception: " + e.ToString(); log.WriteEntry(message); } } throw new ProviderException(exceptionMessage, e); } protected override SiteMapNode GetRootNodeCore() { if (_rootNode == null) BuildSiteMap(); return _rootNode; } } }