Does SQL Table name === Class name? and vice-versa? - intersystems-cache

So I'm just learning Cache, and have a question about tables, classes and globals, what's the difference?
I'm doing the tutorial and it seems like, since this is an object-orientated DB that a class is a table and vice versa. So if I create a class and make it persistent with properties, I can use SQL to query it. Is this true? What's a global then?
Reason I ask is because I'm using Management portal for one of our Cache applications and although I can see a table in WinSQL and Documatic, that same table doesn't seem to exist in the class explorer (Under management portal)... can't figure it out, is it hidden? Is there a command to see class def'ns in terminal??
thanks!

In Caché, classes are tables and tables are classes. You can choose when you want to use SQL access and when you want to use Object Oriented access.
Globals are the sparse multidimensional arrays which sit as storage beneath the class/table. Look at the storage definition at the end of your class to see the actual globals that your persistent class is stored in (e.g. ^Sample.PersonD)
By default, class names are projected as table names, but there are some rules which apply in order to ensure that the table names comply with SQL standards:
if you have a class that is a couple of packages deep (e.g. MyApp.Data.Person) then all but the last "." will be replaced by "_" in the table name (e.g. MyApp_Data.Person would be the table name)
You can't use reserved SQL keywords in table names, so if you make something in the User package for example (class: User.Person) then Caché will change the Package name (e.g. SQLUser.Person would be the name of the table)
I suggest you refer to http://docs.intersystems.com/cache20141/csp/docbook/DocBook.UI.Page.cls?KEY=GORIENT_ch_persistence for more detail

Related

How to set attribute value to instance of class at runtime

I'm on Enterprise Architect 14. I have a component diagram containing an interface User and two classes Employee and Customer, which both realize interface User.
Furthermore I created two instances, one of each class and specified the values of the attributes via Features & Properties > Set Run State....
Next I created a component with 2 attributes, one of type Employee and one of type Customer. Then I created an instance of the component.
Now I would like to set run state of the component instance by assigning ArbitraryUser to the Employee attribute and ArbitraryCustomer to the Customer attribute of the component instance. According documentation this should be possible (see here).
At run-time, an Object instance can have specific values for its attributes, or exist in a particular state. To model the varying behavior of Objects at run-time, use instance values selected from the 'Select ' dialog and run-time states or run-states.
However I could not figure out how to do so. Can someone help me?
AFAIK that is not possible.
I'm not sure what the quote from the help really means, but I've only ever been able to type a value for the run state.
An partial alternative would be to use associations rather than attributes to model such relations. Then you can create a link as an instance of the association to relate instances of Employee or Customer with instances of a ArbitraryComponent.
This solution doesn't work for datatypes, but it seems a bit far fetched to start modelling instances of datatypes.

Do classes necessarily have to exist prior to record insertion?

I'm coming from Neo4j and evaluating OrientDB, and I had a quick question about classes - do they have to exist prior to inserting a record? That is, in Neo4j there's the 'MERGE' command, which will update or create a node if it doesn't exist. Classes seem roughly equivalent to Neo4j's labels, and if a label doesn't exist when performing a MERGE, it will be created. Is there similar functionality in OrientDB? Currently when I try to insert a record whose class doesn't exist, OrientDB throws an exception, "Class SOME_CLASS not found in database".
I've been reading through the docs trying to get a handle on the various data models available, but I can't find anything explicit on this issue. One thing I tried was to add a cluster, and then insert a record with a class that does not exist. This worked, and in OrientDB Studio, under 'DB', I see the cluster with number of records equal to '1'; however, the class of that new record does not appear under 'Schema'.
If dynamic class creation of this sort isn't possible, is it acceptable to check if a class exists in the schema, and if not, create it, and then proceed with creating the record? A different question is, if it's acceptable, is it good to do this, or should I always define the schema manually?
If you use one of the CREATE commands, then the object is placed in a default class; for example:
CREATE VERTEX
Created vertex 'V#9:0 v1' in 0.047000 sec(s).
(In this case, the class is V.)
And of course if you use the INSERT INTO ... form, then you have to specify a class.
So perhaps your first question boils down to whether it is possible to change the class of an OrientDB vertex or edge.
It is possible to change the parent class of a vertex -- see
http://orientdb.com/docs/2.1/SQL-Move-Vertex.html -- but there are important caveats.
To test whether a class exists programmatically, see e.g. this SO entry:
Check if class exists or not in orientdb
This gives a Java example, but a similar approach is possible using other supported languages.
As to the wisdom of changing the class of an entity dynamically -- perhaps the safe answer is that if you can achieve whatever you want using a property label, then use labels.

How do include a global's extended reference when creating a class using cache sql storage?

I am creating a class that is mapped to an existing global so it uses cache sql storage not default storage. This class has extended references (UCKE, SYKE) whose values are set at run-time. How do I include the extended reference in the sql storage map? I can't seem to find any Intersystmes documentation about this.
Well, it's not entirely clear what specific problem you are running into. I just tested a class where I opened Cache Studio, went to the Object Inspector, selected Storage, went down to the row that shows SQL Storage Map, clicked the ellipsis that appear when that row is selected, selected the master map, and for the global name set it to ^[UCKE]MyGlobal. This generated correct .INT code for SQL statements.
Are you having problems making sure the local variables are set when the SQL runs? Did I just not understand what you were doing?

Is there a way of avoiding 2 repository objects for the same database table?

Im currently working in a team that uses EF as the ORM of choice.
We have a common project that contains many EDMX files.
The reason for this is to keep the EDMX files small and manageable while also allowing them to focus on a conceptual set of tables on the database.
Eg
Orders.edmx
Users.edmx
Trades.edmx
These all point to a different set of tables on the same db.
I now need to add the user table to the Trade.edmx file. Since the user table is already in the user.edmx file, this creates the same User type twice under a different namespace which means I would need 2 UserRepository objects.
Common.data.trade.User
Common.data.users.User
Is there a way of avoiding 2 repository objects for the same table?
Any suggestions would be greatly appreciated
If you are using POCO generator you can update template for Trades.edmx to not generate new User class and its context template to use User class from Users namespace. EF matches POCO classes with entities in designer only by the class name (namespace is omitted) so it will work.
The disadvantage is that you have User entity in two mapping files and you must update it in both files or your application throw exception at runtime.
The reason for this problem is your architecture - at the beginning you wanted separated models but know you want to combine entities from different models. Those are contradicting requirements. Either use separated model where Trade knows only userID without any navigation property (like if it is defined in another database) or move all entities to single EDMX to support your new requirements.

advantages of synonyms IN SQL?

why synonyms are used?,advantages of syNONYMS IN SQL?
They're just shorthand names for objects inside a database. For example, you can create a synonym called Products if you have a namespace'd table in a database called ProductionControl.Inventory.Products. They're also handy for controlling named access to other databases in stored procedures. If you have SPs that refer to tables in other databases, creating a synonym and using that instead gives you more control in case the target of the synonym ever changes. This is useful in scenarios where you have SPs that refer to a development database, but when you deploy to production the name is different. So you'd just update the synonym and you'd be OK.
From MSDN Understanding Synonyms
A synonym is a database object that
serves the following purposes:
Provides an alternative name for another database object, referred to
as the base object, that can exist on
a local or remote server.
Provides a layer of abstraction that protects a client application
from changes made to the name or
location of the base object.
In some enterprise systems, you may have to deal with remote objects over which you have no control. For example, a database that is maintained by another department or team.
Synonyms can help you decouple the name and location of the underlying object from your SQL code. That way you can code against a synonym table even if the table you want is moved to a new server/database or renamed.
For example, I could write a query like this:
insert into MyTable
(...)
select ...
from remoteServer.remoteDatabase.dbo.Employee
but then if the server, or database, schema, or table changes it would impact my code. Instead I can create a synonym for the remote server and use the synonym instead:
insert into MyTable
(...)
select ...
from EmployeeSynonym
If the underlying object changes location or name, I only need to update my synonym to point to the new object.
http://www.mssqltips.com/sqlservertip/1820/use-synonyms-to-abstract-the-location-of-sql-server-database-objects/