0% found this document useful (0 votes)
655 views69 pages

Mapping Existing Globals To Objects and SQL: Mike Larocca Intersystems Corporation

This document discusses different strategies for mapping existing global data structures to objects and SQL in Caché: CacheStorage automatically maps globals to objects, CacheSQLStorage maps globals to objects and SQL through defined mappings, and CustomStorage requires manually implementing object access methods when existing globals cannot be easily mapped. CacheSQLStorage is demonstrated by mapping sample data with parent-child relationships to related persistent classes and SQL tables through the mapping definitions.

Uploaded by

nrknrk_nrk
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
655 views69 pages

Mapping Existing Globals To Objects and SQL: Mike Larocca Intersystems Corporation

This document discusses different strategies for mapping existing global data structures to objects and SQL in Caché: CacheStorage automatically maps globals to objects, CacheSQLStorage maps globals to objects and SQL through defined mappings, and CustomStorage requires manually implementing object access methods when existing globals cannot be easily mapped. CacheSQLStorage is demonstrated by mapping sample data with parent-child relationships to related persistent classes and SQL tables through the mapping definitions.

Uploaded by

nrknrk_nrk
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 69

Mapping Existing Globals to

Objects and SQL


Mike LaRocca
InterSystems Corporation
Agenda
Storage Strategy Overview

CacheStorage

CacheSQLStorage

CustomStorage

CacheSQLStorage Example
Storage Strategy Comparisons

CacheStorage CacheSQLStorage CustomStorage

SQL   
Objects   

 Automatically provided by Caché


Cach
 Manually provided by database designer
Choosing Your Storage Strategy
• CacheStorage is ideal for brand new applications
• CacheSQLStorage is typically used where existing global
structures can be expressed relationally, and Object access
can be code-generated based on SQL statements
• CustomStorage is used when existing global structures
can or cannot be expressed relationally, and complex logic
must be used to provide Object access
Agenda
Storage Strategy Overview

CacheStorage

CacheSQLStorage

CustomStorage

CacheSQLStorage Example
CacheStorage Overview
Application

%LoadData %SaveData %DeleteData Object API

ObjectScript ObjectScript ObjectScript


Object
Implementation

Globals
CacheStorage Notes

• CacheStorage generates list-based global structures


• The unique identifier (IDKey / PrimaryKey) can be
automatically generated or supplied by the application
• This influences what the global subscripts look like

• The list-based data can be re-ordered


• This influences what the global values look like
Agenda
Storage Strategy Overview

CacheStorage

CacheSQLStorage

CustomStorage

CacheSQLStorage Example
CacheSQLStorage Overview
Application

%LoadData %SaveData %DeleteData Object API

SELECT
INSERT /
DELETE
SQL
UPDATE
Implementation

Globals
CacheSQLStorage Mapping –
A Bird’s Eye View
• Create a Persistent Class
• Add properties to your new class
• Figure out which property (or properties) will be your
unique identifier (IDKey / Primary Key) for the class
• Create a storage strategy, mapping your class properties to
your global data
CacheSQLStorage Maps

• CacheSQLStorage maps are typically created by:


• A programmer / database designer
• F-DBMS conversion program
• KB-SQL conversion program
What Type of SQL Access is Allowed?
• Not all global structures can be easily mapped for full
Read/Write/Delete access
• Many table mappings of legacy global structures are for
SELECT only
• If full update access is also required, some additional work
outside of the “typical” mapping requirements might be
necessary
Map Types

• CacheSQLStorage maps come in a few flavors:


• Data (aka MasterMap): All fields must be represented here
• Index: A subset of fields are represented here
• Full (default): All data is populated within the index
• Conditional: Data is populated only if a condition is satisfied
• Nonnull: Null values are not populated within the index
Mapping Concepts: ID / Primary Keys

• IDKey indexes declare the unique identifier for objects


• Primary Key indexes declare the unique identifier for SQL
• IDKeys and Primary Keys are typically based on the same
field(s)
Mapping Concepts: Subscripts

• Map subscripts are typically equivalent to global subscripts


• Types of subscript access supported:
Sub: Based on a “standard” global subscript
Piece: Based on a certain position, using a delimiter
Global: Based on data stored in multiple globals
Other: Based on user-written code
Mapping Concepts: RowIDs
• There’s a close relationship between the IDKey and the
RowID for data maps, but not necessarily for index maps
• A RowID is used to uniquely identify data in a global,
based on the subscripts defined in the map defintion
• For example, if our global structure was this:
^Person(PersonID,“Cars”,CarID)=“Make^Model^Year”
We would have 2 fields in our RowID:
PersonID: Stored in level 1 of the global, or {L1}
CarID: Stored in level 3 of the global, or {L3}
Mapping Concepts: Data Fields

• Once subscripts mappings are defined, the next step is to


map fields to a specific location in the global
• Additional subscript nodes (literals only) can be defined
• Data can be positioned within a string according to a given
delimiter or list element
Map Editor: Detail
• Map Name: Must begin with a letter, proceeded by alpha-numeric
• Map Type: Data or Index
• Global Name: Name of global with ^ in front, or local array
• Node Structure: $Piece (typical) or $List (introduced in Caché 2.1)
• Population Type: Define how the map will be populated
• Population %: Estimate percentage of number of rows in this index
• Condition: Expression which defines the condition, such as {Name}‘=“”
• Conditional Fields: Field(s) on which the condition is tested
• Conditional with hostvars: Boolean which influences cached queries’ use of index
• Row Reference: Allows programmers to override the generated RowID
Subscript Editor: Detail
• Access Type: Sub, Piece, Global, or Other
• Delimiter: Only used if Access Type is Piece
• Expression: Typically the {field}, “string” or numeric literal, or delimited position
• Loop Init Value: Non-inclusive value used in generated traversal code
• Start Value: Inclusive value used in generated traversal code
• Stop Value: Literal value at which traversal code should terminate
• Stop Expression: Expression used to terminate traversal code, such as {L1}>200
• Data Access: Override the context of the current access-level’s value expression
• Next Code: Used by programmers to override generated traversal code
• Invalid Conditions: Expression used to filter rows out of the map, such as {L1}<1
• Access Variables: Variables used by programmer, guaranteed to have unique names
RowID Editor: Detail
• RowID: Position a field has within the full RowID specification
• Field: Name of the field that makes up this part of the RowID
• Expression: The level within the subscript definition, such as {L2} or {L6}
Data Editor: Detail
• Field: Name of the field being mapped on the right-side of = sign
• Node: An additional subscript (literal only) where this field exists
• Piece: Position in the string using the supplied delimiter
• Delimiter: Specifies which delimiter to use, such as “^” or $c(1)
Agenda
Storage Strategy Overview

CacheStorage

CacheSQLStorage

CustomStorage

CacheSQLStorage Example
CustomStorage Overview
Application

%LoadData %SaveData %DeleteData Object API

? ? ?
Custom
Implementation

Globals
CustomStorage Mapping –
A Bird’s Eye View
• Create a Persistent Class
• Add properties to your new class
• Figure out which property (or properties) will be your
unique identifier (IDKey / Primary Key) for the class
• Create a storage strategy, mapping your class properties to
your global data
• Implement the Object access code, namely: %LoadData,
%SaveData, %DeleteData
CustomStorage and SQL

• In order to use SQL with CustomStorage, you must define


a special parameter within your class:
Parameter SQLENABLED = 1;
• Mapping the SQL portion with CustomStorage is identical
to the methods used for CacheSQLStorage
CustomStorage and Objects
• In order to use Objects with CustomStorage, you must do
the following:
• Implement %LoadData, %SaveData, %DeleteData
• Within your code, you must manage:
• Object IDs on disk and in memory (via the %IdSet() method)
• Property instance variables (property names with “i%” in front)
• Concurrency
• Data uniqueness
• Foreign key constraints
%LoadData
• Code implemented by %LoadData() will be executed each time an
object is loaded, typically from %Open() and %OpenId()
• %LoadData example:
Method %LoadData(id As %Library.String) As %Library.Status
{
Set i%SSN = id
Set i%Name = $Piece(^P(id),“^”,1)
Set i%DOB = $Piece(^P(id),“^”,2)

Quit $$$OK
}
%SaveData
• Code implemented by %SaveData() will be executed each time an
object is saved by calling the %Save() method
• %SaveData Example:
Method %SaveData(id As %Library.String) As %Library.Status
{
Lock ^P(id):5 If '$Test Quit $$$ERROR($$$LockFailedToAcquireExclusive)

Set id = i%SSN
Do ..%IdSet(id)

Set $Piece(^P(id),”^”,1) = i%Name


Set $Piece(^P(id),”^”,2) = i%DOB

Quit $$$OK
}
%DeleteData
• Code implemented by %DeleteData will be executed each time an
object is deleted, by calling %Delete() or %DeleteId()
• %DeleteData example:
Method %DeleteData(id As %String, concurrency as %Integer) As %Status
{
Lock ^P(id):5 If '$Test Quit $$$ERROR($$$LockFailedToAcquireExclusive)

Kill ^P(id)

Quit $$$OK
}
Agenda
Storage Strategy Overview

CacheStorage

CacheSQLStorage

CustomStorage

CacheSQLStorage Example
Example Data Model
Patient
Address

Phone
Doctor Visits
Numbers

• Two Parent-Children relationships exist:


• A Patient can have many phone numbers
• A Patient can have many doctor visits

• Deleting a patient should delete all related phone numbers & visits
Example Data Global Structure
^P(SSN) = “Name^DOB^Phone1~Phone2~...~PhoneN^Company”
^P(SSN,“Address”) = “City^PostalCode^Country”
^P(SSN,“Visits”,VisitDate,VisitTime) = “Symptom^Payment”

^P(“211-22-1222”) = “Smith,John^39873^718-317-3312~917-225-2213^AT&T”
^P(“211-22-1222”,“Address”) = “New York^10312^USA”
^P(“211-22-1222”,“Visits”,58809,43200) = “Cough^15.00”
^P(“211-22-1222”,“Visits”,58820,57900) = “Sore Throat^50.00”
Example Index Global Structure

^PI(Name,SSN) = “”

^PI(“Smith,John”,“211-22-1222”) = “”
Create a Persistent Class
Add Properties
Choose a Unique Identifier

• Our identifier will be based on 1 field: SSN


Declare an ID / Primary Key Index

• Base this index on the SSN property


• Don’t modify the index collation
Create a Storage Definition
Create a Data Map

• Map names cannot have spaces


Define the Global Subscripts

• Subscript level 1 is based on SSN


Define the Row ID

• Row ID 1 is based on SSN in subscript level 1


Define the Property Mappings

• Enter delimiter and additional node information


Create an Index Map

• Choose a population type of ‘full’


Define the Index Subscripts
Define the Index Row ID

• Row ID 1 is based on SSN in subscript level 2


Save and Compile Class
Create a PhoneList Child Table

• This class will also be persistent


Create the Parent-Child Relationship

• Relationships are special types of properties


• In addition to naming the property in this class (PatientRef here), you must
also specify the inverse side of the relationship (PhoneNumbers here)
Add Additional Properties

• In addition to defining a phone number, we must also define a property to


represent the position within the embedded delimited string (Counter here)
Choose a Unique Identifier

• Our identifier will be based on 1 field: Counter


Declare an ID / Primary Key Index

• Base this index on the Counter property


• Don’t modify the index collation
• The PatientRef property is implicitly part of the IDKey / Primary Key
Create a Storage Definition
Create a Data Map

• Map names cannot have spaces


Define the Global Subscripts

• Subscript level 1 is based on Training.Patient.SSN


• Subscript level 2 is based on the “^” delimiter, using the 3rd position
• Subscript level 3 is based on the “~” delimiter, using Counter for position
Define the Row ID

• Row ID 1 is based on Training.Patient.SSN in subscript level 1


• Row ID 2 is based on Counter in subscript level 3
Define the Property Mappings

• Here, you can enter HomePhone with no additional specifications


Save and Compile Class
Create a Visit Child Table

• This class will also be persistent


Create the Parent-Child Relationship

• In addition to naming the property in this class (PatientRef here), you must
also specify the inverse side of the relationship (Visits here)
Add Additional Properties
Choose a Unique Identifier

• This time, our identifier will be based on 2 fields: VisitDate and VisitTime
Declare an ID / Primary Key Index

• Base this index on the VisitDate and VisitTime properties


• Don’t modify the index collation
• The PatientRef property is implicitly part of the IDKey / Primary Key
Create a Storage Definition
Create a Data Map

• Map names cannot have spaces


Define the Global Subscripts

• Subscript level 1 is based on Training.Patient.SSN


• Subscript level 2 is a string literal: “Visits”
• Subscript level 3 is based on VisitDate
• Subscript level 4 is based on VisitTime
Define the Row ID

• Row ID 1 is based on Training.Patient.SSN in subscript level 1


• Row ID 2 is based on VisitDate in subscript level 3
• Row ID 3 is based on VisitTime in subscript level 4
Define the Property Mappings
Save and Compile Class
Mapping Existing Globals to
Objects and SQL
Mike LaRocca
InterSystems Corporation

You might also like