/// <summary> /// This function is overriden to control trigger names uniques for whole database and /// not for each table. /// </summary> /// <param name="hierarchy">Server explorer facade object to be used for Server Explorer hierarchy interaction.</param> /// <param name="typeName">Object type name.</param> /// <param name="id">Array with object identifier.</param> /// <param name="template">Template for the new object identifier.</param> protected override void CompleteNewObjectID(ServerExplorerFacade hierarchy, string typeName, ref object[] id, string template) { if (hierarchy == null) { throw new ArgumentNullException("hierarchy"); } if (typeName == null) { throw new ArgumentNullException("typeName"); } if (id == null) { throw new ArgumentNullException("id"); } if (id.Length < 3 || id[2] == null) { throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Resources.Error_InvlaidIdentifier, id.Length, typeName, ObjectDescriptor.GetIdentifierLength(typeName)), "id"); } if (String.IsNullOrEmpty(template)) { throw new ArgumentException(Resources.Error_EmptyString, "template"); } // Initialize complete parameters string actualTameplate = template; int counter = 0; do { // Stores table id and reset it to null in template, because trigger names must be // unique for a whole database. object tableID = id[2]; id[2] = null; // Use base method for completion base.CompleteNewObjectID(hierarchy, typeName, ref id, actualTameplate); // Restores table id id[2] = tableID; // Change template and add new counter actualTameplate = template + (++counter).ToString(); } // We need to control open editors here separately, because base method will miss them // (it doesn't know table ID) while (hierarchy.HasDocument(typeName, id)); }
/// <summary> /// This function is overriden to control trigger names uniques for whole database and /// not for each table. /// </summary> /// <param name="hierarchy">Server explorer facade object to be used for Server Explorer hierarchy interaction.</param> /// <param name="typeName">Object type name.</param> /// <param name="id">Array with object identifier.</param> /// <param name="template">Template for the new object identifier.</param> protected override void CompleteNewObjectID(ServerExplorerFacade hierarchy, string typeName, ref object[] id, string template) { if (hierarchy == null) throw new ArgumentNullException("hierarchy"); if (typeName == null) throw new ArgumentNullException("typeName"); if (id == null) throw new ArgumentNullException("id"); if(id.Length < 3 || id[2] == null) throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Resources.Error_InvlaidIdentifier, id.Length, typeName, ObjectDescriptor.GetIdentifierLength(typeName)), "id"); if (String.IsNullOrEmpty(template)) throw new ArgumentException(Resources.Error_EmptyString, "template"); // Initialize complete parameters string actualTameplate = template; int counter = 0; do { // Stores table id and reset it to null in template, because trigger names must be // unique for a whole database. object tableID = id[2]; id[2] = null; // Use base method for completion base.CompleteNewObjectID(hierarchy, typeName, ref id, actualTameplate); // Restores table id id[2] = tableID; // Change template and add new counter actualTameplate = template + (++counter).ToString(); } // We need to control open editors here separately, because base method will miss them // (it doesn't know table ID) while (hierarchy.HasDocument(typeName, id)); }
/// <summary> /// Completes identifier for new object. Last element of id array considered as the name of new object. This /// method sequentially generates new names in form {template}{N} and checks for existing object with same name. /// To check it this method tries to enumerate objects with restriction to whole id. /// </summary> /// <param name="hierarchy">Server explorer facade object used to check for existen objects.</param> /// <param name="typeName">Object type name.</param> /// <param name="id">Array with object identifier.</param> /// <param name="template">Template for the new object identifier.</param> public static void CompleteNewObjectID(ServerExplorerFacade hierarchy, string typeName, ref object[] id, string template) { if (hierarchy == null) { throw new ArgumentNullException("hierarchy"); } if (typeName == null) { throw new ArgumentNullException("typeName"); } if (id == null) { throw new ArgumentNullException("id"); } if (String.IsNullOrEmpty(template)) { throw new ArgumentException(Resources.Error_EmptyString, "template"); } // Retrieve connection information DataConnectionWrapper connection = hierarchy.Connection; Debug.Assert(connection != null, "Empty connection object!"); if (connection == null) { return; } // Calculate "name" part of identifier (it is the last part) int nameIdPart = id.Length - 1; Debug.Assert(nameIdPart >= 0, "Could not complete empty identifier!"); if (nameIdPart < 0) { return; } // Initialize search context int objectIndex = 0; DataTable objectTable = null; bool objectsFounded = false; // Generate object name in <typeName><N> style do { // Build exact identifier id[nameIdPart] = template + (++objectIndex).ToString(CultureInfo.InvariantCulture); objectsFounded = false; try { // Look for exisiting object with this identifier objectTable = EnumerateObjects(connection, typeName, id, null); objectsFounded = objectTable != null && objectTable.Rows != null && objectTable.Rows.Count > 0; } finally { // Release resources if (objectTable != null) { objectTable.Dispose(); } objectTable = null; } // Look for registered document (may be second new object) objectsFounded = objectsFounded || hierarchy.HasDocument(typeName, id); } // Trying while objects are exists and objectIndex less when MaxObjectIndex while (objectsFounded && objectIndex < MaxObjectIndex); }
/// <summary> /// Drops single item. Uses object descriptor to build DROP statement. /// </summary> /// <param name="hierarchy">Server explorer facade object to be used for Server Explorer hierarchy interaction.</param> /// <param name="item">Item identifier.</param> /// <returns>Result of execution. Typicaly null.</returns> protected override object ExecuteSingleItem(ServerExplorerFacade hierarchy, int item) { if (hierarchy == null) throw new ArgumentNullException("hierarchy"); if (item < 0) throw new ArgumentOutOfRangeException("item"); // Extract type name string typeName = GetObjectType(hierarchy, item); if (String.IsNullOrEmpty(typeName)) { Debug.Fail("Failed to get object type!"); return false; } // Extract descriptor IObjectDescriptor descriptor = ObjectDescriptorFactory.Instance.CreateDescriptor(typeName); if (descriptor == null || !descriptor.CanBeDropped) { Debug.Fail("Failed to get descriptor or descriptor doesn't support dropping!"); return null; } // Extract object identifier object[] identifier = hierarchy.GetObjectIdentifier(item); if (identifier == null) { Debug.Fail("Failed to get object identifier!"); return null; } // TODO: Note the seconde check for TableData document. It should be replaced in the future // by the generic mechanism. // Check if editor is registered for the database object if (hierarchy.HasDocument(typeName, identifier) || hierarchy.HasDocument(TableDataDescriptor.TypeName, identifier)) { UIHelper.ShowError(String.Format( CultureInfo.InvariantCulture, Resources.Error_CantDropBecauseOfEditor, hierarchy.GetName(item))); return null; } // Build DROP query string dropQuery = String.Empty; if (descriptor is StoredProcDescriptor) dropQuery = (descriptor as StoredProcDescriptor).BuildDropSql( hierarchy, item, identifier); else dropQuery = descriptor.BuildDropSql(identifier); if (String.IsNullOrEmpty(dropQuery)) { Debug.Fail("Failed to build DROP query!"); return null; } // Extract connection DataConnectionWrapper connection = hierarchy.Connection; if (connection == null) { Debug.Fail("Failed to extract connection!"); return null; } try { // Execute drop query connection.ExecuteScalar(dropQuery); // Drop hierarchy node hierarchy.DropObjectNode(item); // Notify everybody about object dropping connection.ObjectChangeEvents.RaiseObjectRemoved(typeName, identifier); } catch (DbException e) { Trace.TraceError("Error during saving object:\n{0}", e.ToString()); SqlErrorDialog.ShowError(e, connection.GetFullStatus()); } catch (Exception e) { Trace.TraceError("Error during saving object:\n{0}", e.ToString()); UIHelper.ShowError(e); } return null; }
/// <summary> /// Drops single item. Uses object descriptor to build DROP statement. /// </summary> /// <param name="hierarchy">Server explorer facade object to be used for Server Explorer hierarchy interaction.</param> /// <param name="item">Item identifier.</param> /// <returns>Result of execution. Typicaly null.</returns> protected override object ExecuteSingleItem(ServerExplorerFacade hierarchy, int item) { if (hierarchy == null) { throw new ArgumentNullException("hierarchy"); } if (item < 0) { throw new ArgumentOutOfRangeException("item"); } // Extract type name string typeName = GetObjectType(hierarchy, item); if (String.IsNullOrEmpty(typeName)) { Debug.Fail("Failed to get object type!"); return(false); } // Extract descriptor IObjectDescriptor descriptor = ObjectDescriptorFactory.Instance.CreateDescriptor(typeName); if (descriptor == null || !descriptor.CanBeDropped) { Debug.Fail("Failed to get descriptor or descriptor doesn't support dropping!"); return(null); } // Extract object identifier object[] identifier = hierarchy.GetObjectIdentifier(item); if (identifier == null) { Debug.Fail("Failed to get object identifier!"); return(null); } // TODO: Note the seconde check for TableData document. It should be replaced in the future // by the generic mechanism. // Check if editor is registered for the database object if (hierarchy.HasDocument(typeName, identifier) || hierarchy.HasDocument(TableDataDescriptor.TypeName, identifier)) { UIHelper.ShowError(String.Format( CultureInfo.InvariantCulture, Resources.Error_CantDropBecauseOfEditor, hierarchy.GetName(item))); return(null); } // Build DROP query string dropQuery = String.Empty; if (descriptor is StoredProcDescriptor) { dropQuery = (descriptor as StoredProcDescriptor).BuildDropSql( hierarchy, item, identifier); } else { dropQuery = descriptor.BuildDropSql(identifier); } if (String.IsNullOrEmpty(dropQuery)) { Debug.Fail("Failed to build DROP query!"); return(null); } // Extract connection DataConnectionWrapper connection = hierarchy.Connection; if (connection == null) { Debug.Fail("Failed to extract connection!"); return(null); } try { // Execute drop query connection.ExecuteScalar(dropQuery); // Drop hierarchy node hierarchy.DropObjectNode(item); // Notify everybody about object dropping connection.ObjectChangeEvents.RaiseObjectRemoved(typeName, identifier); } catch (DbException e) { Trace.TraceError("Error during saving object:\n{0}", e.ToString()); SqlErrorDialog.ShowError(e, connection.GetFullStatus()); } catch (Exception e) { Trace.TraceError("Error during saving object:\n{0}", e.ToString()); UIHelper.ShowError(e); } return(null); }
/// <summary> /// Completes identifier for new object. Last element of id array considered as the name of new object. This /// method sequentially generates new names in form {template}{N} and checks for existing object with same name. /// To check it this method tries to enumerate objects with restriction to whole id. /// </summary> /// <param name="hierarchy">Server explorer facade object used to check for existen objects.</param> /// <param name="typeName">Object type name.</param> /// <param name="id">Array with object identifier.</param> /// <param name="template">Template for the new object identifier.</param> public static void CompleteNewObjectID(ServerExplorerFacade hierarchy, string typeName, ref object[] id, string template) { if (hierarchy == null) throw new ArgumentNullException("hierarchy"); if (typeName == null) throw new ArgumentNullException("typeName"); if (id == null) throw new ArgumentNullException("id"); if (String.IsNullOrEmpty(template)) throw new ArgumentException(Resources.Error_EmptyString, "template"); // Retrieve connection information DataConnectionWrapper connection = hierarchy.Connection; Debug.Assert(connection != null, "Empty connection object!"); if (connection == null) return; // Calculate "name" part of identifier (it is the last part) int nameIdPart = id.Length - 1; Debug.Assert(nameIdPart >= 0, "Could not complete empty identifier!"); if (nameIdPart < 0) return; // Initialize search context int objectIndex = 0; DataTable objectTable = null; bool objectsFounded = false; // Generate object name in <typeName><N> style do { // Build exact identifier id[nameIdPart] = template + (++objectIndex).ToString(CultureInfo.InvariantCulture); objectsFounded = false; try { // Look for exisiting object with this identifier objectTable = EnumerateObjects(connection, typeName, id, null); objectsFounded = objectTable != null && objectTable.Rows != null && objectTable.Rows.Count > 0; } finally { // Release resources if (objectTable != null) objectTable.Dispose(); objectTable = null; } // Look for registered document (may be second new object) objectsFounded = objectsFounded || hierarchy.HasDocument(typeName, id); } // Trying while objects are exists and objectIndex less when MaxObjectIndex while (objectsFounded && objectIndex < MaxObjectIndex); }