Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Geert Bellekens

Pages: 1 ... 514 515 [516] 517 518 ... 548
Automation Interface, Add-Ins and Tools / Re: Open a View programmatically?
« on: September 13, 2010, 04:44:15 pm »
"fist" state machine. Vienna is back in the ring!


Oh, should at least have been "frist statemachine" ;)



The Diagram.ParentID is filled in automatically when a diagram is owned by an element (and not a package).



This seems like a pretty weak link between use case and component to me.

You could make the relation a bit more explicit by adding the use case on the diagram, launching the first message.

If you are using the API you can get the nested diagrams using Element.Diagrams.
The other way around, the diagram keeps the id of the use case in the ParentID field.

The elements displayed on a diagram can be investigated using Diagram.DiagramObjects. Use the DiagramObject.ElementID to get the ID of the component instance.
The ClassifierID of the componentInstance will then point to the actual component.



How exactly do you model the relation between the use case and the component (instance)?
Do I read it correctly that you have sequence diagrams nested under the use case, and on those sequence diagrams there are instances of components that either send or receive messages?



Try "Save As" when connected to one of those repositories.
This will create an .eap "shortcut" file that contains the connection string.
Alternatively use Repository.ConnectionString when connected tot the repository.



What you could do for attributes, connector, ... is to get the id's from the database using either Repository.SQLQuery, or use one of the enumerate operations on the Project Interface.
And then use the Repository.GetXXXByID operations to get the actual objects.
But i'm not sure that will make a big difference in the performance.

For reference, my modelvalidator runs about 15 minutes on a package (and subpackages) with about 5000 elements.
It returns about 20.000 errors in an excel file.
The whole model contains about 50.000 elements and is stored on a remote SQL Server database.


I do need the whole content of the EA model, because my application is a validation engine with many rules to check the UML model content against.

Ha, same here ;D
The performance issues were exactly the reason why I used the operation I posted above.
I think you'll find that is it faster then recursing the whole model.
Filling the element cache takes about three minutes for about 5.000 elements.



Do you create a complete in-memory model, or do you use a lazy loading principle for creating the in-memory model.
Depending on the type of application you are writing that could make a big difference.
If you only need a part of the objects then you don't need to build the whole model in memory, just instantiate what you need.



The biggest bottleneck in EA performance (and the tools you write agains its API) are the enormous amounts of database calls.
For some EA collection, merely iterating the collection results in two database calls for each iteration.
So the only way I see to avoid the database calls is to group the database calls into one SQL statement, retrieving all I need to know.
Remember, creating the Objects, and iterating the collections is what takes most time, so avoid this if possible.
Only instantiate an EA object if you really need it, and only iterate a specific collection once.



The speed of EA is what it is.
How do those 14 seconds compare to opening the model using the EA client?
Building a full cached representation trough recursion is a BAD idea.
That will take ages.
What I do to cache my elements is use the Repository.GetElementSet.
If I need attributes, operations, or connectors then I first get a list of id's using Repository.SQLQuery and then get the item using the Repository.getXXXbyID operations.

Here's an example of my caching operation for elements for our SQL server repository. The same can be done with a local eap file, but then you'll have to rewrite the query to match to Access "SQL" syntax.
Code: [Select]
/// <summary>
        /// adds all elements in the model to the cache
        /// </summary>
        public void addAllElementsToCache(string startingPackageID)
            //first check if we are dealing with a local eap file in MS Access format.
            //in that case we cannot perform the query with the unions
            bool localEAPFile = true;
            string connection = this.wrappedModel.ConnectionString;
            if (connection.ToLower().EndsWith( ".eap"))
                //could be an eap file, or could be a shortcut file.
                //figure it out based on the size of the file
                FileInfo connectionInfo = new FileInfo(connection);
                if (connectionInfo.Length > 1000)
                    localEAPFile = true;
                    localEAPFile = false;

                }catch (Exception)
                    localEAPFile = false;
            Logger.log("start caching elements");
            //build the sql string to get all the object fromthe starting package and 9 levels of packages underneath.
            //there is a better way using a recursive query, but these are not supported in sql 2000 yet (only from sql 2005)
            string sqlGetElements = @" SELECT o.Object_ID FROM t_object as o
                                    left join t_package p on o.Package_ID = p.Package_ID
                                    left join t_package p2 on p.Parent_ID = p2.Package_ID
                                    left join t_package p3 on p2.Parent_ID = p3.Package_ID
                                    left join t_package p4 on p3.Parent_ID = p4.Package_ID
                                    left join t_package p5 on p4.Parent_ID = p5.Package_ID
                                    left join t_package p6 on p5.Parent_ID = p6.Package_ID
                                    left join t_package p7 on p6.Parent_ID = p7.Package_ID
                                    left join t_package p8 on p7.Parent_ID = p8.Package_ID
                                    left join t_package p9 on p8.Parent_ID = p9.Package_ID

                                    p.package_ID = " + startingPackageID + @"
                                        or p2.package_ID = " + startingPackageID + @"
                                        or p3.package_ID = " + startingPackageID + @"
                                        or p4.package_ID = " + startingPackageID + @"
                                        or p5.package_ID = " + startingPackageID + @"
                                        or p6.package_ID = " + startingPackageID + @"
                                        or p7.package_ID = " + startingPackageID + @"
                                        or p8.package_ID = " + startingPackageID + @"
                                        or p9.package_ID = " + startingPackageID;
                if (!localEAPFile)
                    //we only do caching when working on an remote database
                    EAWrapperFactory.createEAWrappers(this, this.wrappedModel.GetElementSet(sqlGetElements, 2));
                Logger.log("end caching elements");
            catch (Exception)
                // oh well, caching failed, no biggy, we can work without caching, its just a bit slower
                Logger.logError("Caching failed");

Have you reported it to Sparx support?
If this is a bug then they better fix it quickly.


Have you tried deleteAt()?


I think MiscData(3) (t_connector.pdata4) is used to store the isReturn flag.



In order to refresh the image of a diagram you should call Repository.ReloadDiagram (long DiagramID) or Repository.RefreshOpenDiagrams (boolean FullReload)



Pages: 1 ... 514 515 [516] 517 518 ... 548