SlideShare a Scribd company logo
1 
Welcome 
August 18, 2014 
World Headquarters 
Cincinnati, Ohio 
How and Where in GLORP: GLORP Tutorial Reference 
Slides with Orange Titles: ESUG 2014 Tutorial. 
Slides with Blue Titles: additional GLORP info. 
Niall Ross, Cincom 
GLORP in Cincom® VisualWorks® 
(assist Cincom® ObjectStudio®)
What is GLORP? 
•Generic: abstract, declarative, multi-platform f/w 
•Lightweight: looks like Smalltalk 
session read: Customer where: [:each | each orders size > 0] 
•Object: general hierarchic OO models 
no ActiveRecord-like style restriction 
remains flexible throughout the lifecycle 
•Relational: embedded or bound SQL 
•Persistence: transactions, constraints, indexes
Glorp Documentation 
•GLORP is amazing 
GLORP’s documentation is less amazing  
Nevin Pratt’s GlorpUserGuide0.3.pdf (in preview/glorp) 
(paraphrase) “Before displaying Glorp’s amazing power, I will summarise its raw rear end and show how that could be driven directly. … Having shown how an idiot would (mis)use GLORP, I will now TO BE COMPLETED.” 
Good summary of the DB-communicating lowest layer 
Roger Whitney’s GLORP Tutorial (www.eli.sdsu.edu/SmalltalkDocs/GlorpTutorial.pdf) 
Good course on basic, and some not so basic, things 
“beLockKey I have no idea what this does. “ 
•The greatest wisdom is to know what you don’t know 
Cincom 
VisualWorks GlorpGuide.pdf – good, getting-started coverage 
ObjectStudio MappingToolUsersGuide.pdf – great tool support 
And last, but not least …
… my ESUG 2013 Talk 
•Walk-through GLORP (with demos) 
Architecture 
Mapping the domain model to the schema 
•initial generating / writing step 
•refining your mappings 
Queries 
Commit / Rollback 
•Focus on some less obvious aspects 
You can all read, and you can all #read: 
Follow-up sessions during the conference
Example of using Glorp in VisualWorks 
•The Store workbook 
Is there anything your CM system isn’t telling you? 
Open the workbook, run the query 
| query | 
query := Query read: StoreBundle where: 
[:each || q | 
q := Query read: StoreBundle where: 
[:eachBundle | eachBundle name = each name]. 
q retrieve: [:x | x primaryKey max]. 
each username = 'aknight' & (each primaryKey = q)]. 
query orderBy: [:each | each timestamp descending]. 
session execute: query.
GLORP Architecture 
Image 
Relational Database 
EXternal Database Interface 
GLORP 
GlorpSession 
UnitOfWork 
DatabaseAccessor 
ExternalDatabaseTransaction 
Transaction 
Domain Class 
GlorpClassModel 
Descriptor 
DescriptorSystem 
DatabaseTable 
DatabaseField 
DatabaseIndex 
DatabaseTableConstraint 
Mapping 
Join 
Table 
Column 
Index 
Constraint 
GlorpAttributeModel 
instvar
Building GLORP Applications: mapping 
•getting started 
greenfields or legacy 
•write the GLORP and generate the schema into the DB 
and/or 
•auto-generate the GLORP mapping from an existing DB schema 
(ObjectStudio has powerful UI toolset to manage this 
Load ObjectStudio-prepared GLORP models in VisualWorks 
and/or (re)generate and refine GLORP models programmatically in VW 
but this talk will do everything programmatically in VisualWorks.) 
•refining / (re)creating in code 
make it run, make it right, make it fast
Subclass DescriptorSystem to model … 
•those (parts of) Smalltalk classes to persist 
classModelFor<DomainClassName>: 
•the database tables you will write to and read from 
tableFor<TABLE_NAME>: 
•the mappings (“descriptors”) between the two 
descriptorFor<DomainClassName>: 
The GLORP f/w finds all the ...For<Name>: methods: creates parameter, names it, calls method with it
Template: Class Model 
classModelFor<DomainClassName>: aClassModel 
aClassModel 
newAttributeNamed: #<instvar> 
type: <InstvarClass>. “e.g. String, Integer” 
...
Class models are simple 
•Annotate persisted parts of class with type information 
Set complex types (and simple if the mapping is tricky) 
aClassModel newAttributeNamed: #account type: Account. 
aClassModel newAttributeNamed: #name type: String. 
Set a collection class if you don’t want OrderedCollection 
aClassModel newAttributeNamed: #copies collection: Bag of: Book. 
•‘direct access’ (instVarAt:{put:} ) is the default 
To instead #perform: getters and setters, do 
(aClassModel newAttributeNamed: …) useDirectAccess: false. 
(can make it default for the whole descriptor system) 
N.B. the index is cached in DescriptorSystem instances
Template: Table 
tableFor<TABLE_NAME>: aTable 
aTable 
createFieldNamed: ‘<column_name>’ 
type: platform <type>. “e.g. varchar: 255” 
...
Table models have more to them 
•Define the table’s fields / columns / attributes 
Set types from DatabasePlatform ‘type’ protocol 
aTable createFieldNamed: ‘id’ type: platform inMemorySequence. 
DatabaseField ‘configuring’ protocol 
•bePrimaryKey, beNullable:, isUnique:, beLockKey, defaultValue: 
Set foreign keys 
aTable 
addForeignKeyFrom: storeId to: (custTable fieldNamed: 'STORE_ID') 
from: custName to: (customerTable fieldNamed: 'CUSTOMERNAME') 
from: custDate to: (customerTable fieldNamed: 'BIRTHDATE'). 
Set indexes 
•beIndexed, addIndexForField:{and:{and:}}, addIndexForFields:
Table models (2) 
•Image-only Keys, Imaginary Tables 
•foreignKey shouldCreateInDatabase: false “just for in-memory structuring” 
An object can map to less than one row 
•EmbeddedValueOneToOneMapping: target object is not stored in a separate table, but as part of the row of the containing object 
or to more/other than one row, e.g. 
•GROUP BY / DISTINCT rows in real table 
•specific fields from multiple tables 
•Some default values need to be platform-aware 
converter := booleanField converterForStType: Boolean. 
booleanField defaultValue: 
(converter convert: false toDatabaseRepresentationAs: booleanField type)
Template: Descriptor 
descriptorFor<ClassName>: aDescriptor 
table := self tableNamed: ‘<TABLE_NAME>’. 
aDescriptor directMapping 
from: #<instvar> 
to: (table fieldNamed: ‘<column_name>’). 
...
Most of the complexity is in Descriptors 
•Each persistent class has a descriptor 
Most of its complexity is in its Mappings and their Joins 
•Descriptors pull together 
table(s) 
mappedFields 
mappings 
•and occasional stuff 
multipleTableJoin 
Cache policy, if different from system
Descriptors: table-level mapping 
•Trivial: one class = one table, one instance = one row 
•Inheritance: 
HorizontalTypeResolver: one table per concrete subclass 
•target may need polymorphicJoin 
FilteredTypeResolver: sparse table with fields of all subclasses 
•General: 
Imaginary tables: embedded mappings, cross-table mappings 
DictionaryMapping: collection type that maps key as well as values 
ConditionalMapping, ConditionalToManyMapping 
•often employ a ConstantMapping as their ‘else’ outcome 
AdHocMapping
Descriptors: field-level mapping 
•Mapping Types 
DirectMapping (DirectToManyMapping): mapping between (collections of) simple types such as Number, String, Boolean, and Timestamp. 
ToOneMapping: as direct, when target is a complex object. 
•EmbeddedValueOneToOneMapping: target object is not stored in a separate table, but rather as part of the row of the containing object 
ToManyMapping: #collectionType: 
•Mapping options 
•#beForPseudoVariable 
use in query, not in Smalltalk class, e.g. DatabaseField>>primaryKeyConstraints 
as an alias, e.g. id, not primaryKey 
•#shouldProxy: false “true is default”
Template: Mapping with Join 
aDescriptor oneToOneMapping 
attrubuteName: #<name>; 
join: (Join 
from: (<table1> fieldNamed: ‘<columnA>’) 
to: (<table2> fieldNamed: ‘<columnB>’) 
…); 
...
Descriptors: field-level mapping - Joins 
Join is a utility class 
Join from: (table fieldNamed: ‘FKey’) to: (otherTable fieldNamed: ‘PKey’) 
from: … to: … 
from: … to: … 
•is both easier and safer than 
… join: [:each | (each foreignKey = other primaryKey) AND: …] 
•because general block expressions must fully define read and write, plus actually it is 
… join: [:other | other myEach …] “join expression from target” 
The mapping deduces as much as it can 
•referenceClass: join: useLinkTable linkTableJoin: targetTableJoin: 
•relevantLinkTableFields: - hints for the link table fields 
#beOuterJoin, #outerJoin: - false by default (and very usually) 
•whether left-side’s unjoined rows discarded or NULL-joined
Parsing Mappings and Queries 
•The message eater (MessageArchiver) eats the block 
•N.B. avoid inlined selectors, e.g. use AND: or & 
•Messages in the block are mapped (in order) to 
Functions 
Mapped symbols: just #anySatisfy: and #select: 
Performed special selectors (Glorp internal or ST mimic) e.g. 
•#isEmpty #notEmpty #asDate #getTable: #getField: #fieldNamed: #parameter: #noneSatisfy: #getConstant: #count: #sum: #min: #max: #average: #sqlSelect: #includes: #aggregate:as: 
Named attributes 
Relationships
Functions are easy to add 
•A basic list of generic functions, e.g 
at: #distinct put: (PrefixFunction named: 'DISTINCT'); 
at: #, put: (InfixFunction named: '||'); 
at: #between:and: put: (InfixFunction named: #('BETWEEN' 'AND')); 
at: #countStar put: (StandaloneFunction named: 'COUNT(*)'); 
at: #cast: put: ((Cast named: 'CAST') separator: ' AS '); 
•... is added to by specific subclasses, e.g. DB2Platform 
at: #days put: ((PostfixFunction named: 'DAYS') type: (self date)); 
enables this to work in DB2 as well 
where: [:each | each startDate + each daysToBonus days < Date today] 
(New feature: Date arithmetic is now better supported)
Sort Order 
•#orderBy: isn't a sortblock. It defines the order field(s) 
query 
orderBy: #name ; 
orderBy: [:each | each address streetNumber descending]. 
•Lacking a suitable field, you can assign one 
mapping 
orderBy: (myTable fieldNamed: 'COLLECTION_ORDER'); 
writeTheOrderField. 
•Or you can sort in Smalltalk 
•anywhere you can specify a collection class, you can also use an instance 
query collectionType: (SortedCollection sortBlock: [:a :b | a isSuffixOf: b]). 
(N.B. if data read via a cursor, Smalltalk-side sorting is iffy)
Template: Session Querying 
aClass := aGlorpSession 
readOneOf: <Class> where: aOneArgBlock. 
someClasses := aGlorpSession 
read: <Class> where: aOneArgBlock … 
(see GlorpSession protocol ‘api/queries’)
Queries 
•The GlorpSession ‘api/queries’ protocol … 
session readOneOf: Book where: [:each | each title = ‘Persuasion’]. 
session read: Book where: [:each | each title like ‘Per%’] orderBy: #author. 
•… duplicates the API of Query class and subclasses 
in complex cases, configure Query then execute: 
previously divergent protocol now deprecated 
•use #read: not #readManyOf: or #returningManyOf: 
•Like Seaside, utility protocol plus cascades 
•#read:limit: #read:where:limit: #read:orderBy: #read:where:orderBy: #count: #count:where:
Grouping by multiple criteria added 
Must not return conflicting values in any of the returned fields 
| books query | 
query := Query read: Book. 
query groupBy: [:each | each title]. 
query groupBy: [:each | each author]. 
query orderBy: [:each | each title]. 
query retrieve: [:each | each title]. 
query retrieve: [:each | each author]. 
query retrieve: [:each | each copiesInStock sum]. 
books := session execute: query. 
B/W-compatible API kept; a few changes made: 
•hasGroupBy -> hasGrouping 
•usesArrayBindingRatherThanGrouping -> usesArrayBindingRatherThanGroupWriting
Query Performance: Reads 
Do as much on server as possible 
•use complex where clause 
•use CompoundQuery 
query1 unionAll: query2 
query1 except: query2 
Configure the query 
•#retrieve: gets less, #alsoFetch: gets more (also #shouldProxy: on mapping) 
•#expectedRows: preps caches 
Exploit database functions 
Use a cursor (not in PostgreSQL as yet) 
•query collectionType: GlorpCursoredStream 
GlorpVirtualCollection wraps a stream internally (size requires separate query)
Query Performance: Reads (2) - DIY 
Prepare your own Glorp Command 
SQLStringSelectCommand new setSQLString: ‘select * from customers’. 
myCommand := SQLStringSelectCommand 
sqlString: 'SELECT id FROM books WHERE title=? AND author= ?’ 
parameters: #(‘Persuasion’ ‘Jane Austen’) “or use :param and a dictionary” 
useBinding: session useBinding 
session: session. 
and run it as a command 
query command: myCommand. 
session execute: query. 
or run it directly against the database 
session accessor executeCommand: myCommand
Symbols, Blocks or Queries as params 
•#where:, #orderBy:, etc. take symbol, block or query 
cloneQuery := Query read: pundleClass where: 
[:each || othersQuery parentIdsQuery | 
parentIdsQuery := Query read: pundleClass where: [:e | e previous notNil]. 
parentIdsQuery retrieve: [:e | e previous id distinct]. 
parentIdsQuery collectionType: Set. 
othersQuery := Query read: pundleClass where: 
[:e | (e id ~= each id) & (e name = each name) & 
(e version = each version) & (e timestamp = each timestamp)]. 
(each timestamp < cutoffTimestamp) 
& (each exists: othersQuery) 
& (each id notIn: parentIdsQuery)]. 
cloneQuery collectionType: Bag. 
Performance sometimes needs all to be done on server.
Invoke Functions via Expressions 
If you want a function to prefix a subselect … 
SELECT distinct A.methodRef FROM tw_methods A WHERE not exists 
(SELECT * FROM tw_methods B WHERE 
B.packageRef not in (25, 36) and A.methodRef = B.methodRef) 
and A.packageRef in (25, 36); 
… call it on the imported parameter 
packageIdsOfInterest := #(25 36). 
query := Query read: StoreMethodInPackage where: 
[:each | (each package id in: packageIdsOfInterest) AND: [each notExists: 
(Query read: StoreMethodInPackage where: 
[:mp | mp definition = each definition 
AND: [mp package id notIn: packageIdsOfInterest]])]]. 
query retrieve: [:each | each definition id distinct].
Template: Session Writing 
session 
beginUnitOfWork; 
register: obj; “obj is a domain instance” 
commitUnitOfWork. 
session inUnitOfWorkDo: [session register: obj]. 
(see GlorpSession protocol ‘api/transactions’)
Transaction (DB) v. UnitOfWork (Image) 
•Transaction: database maintains integrity via transactions, commits or rolls-back changes at transaction boundaries. 
The DatabaseAccessor holds the current transaction 
•UnitOfWork: holds changed objects and their unchanged priors, can roll-back Smalltalk-side changes in the image. 
The GlorpSession holds the current UnitOfWork 
•Users must manage (unavailable) nesting 
#inUnitOfWorkDo: defers to an outer UnitOfWork 
#beginUnitOfWork errors if called within an outer UnitOfWork 
(likewise for #inTransactionDo: versus #beginTransaction)
Transaction v. UnitOfWork (2) 
•#transact: 
puts UnitOfWork inside Transaction, commits/rolls-back both, paired 
•#commitUnitOfWork (or #commitUnitOfWorkAndContinue) 
creates and commits a transaction if none is present 
does not commit if a transaction is present 
•#doDDLOperation: 
for table creation, deletion, alteration; some databases require a transaction in those cases, others do not 
•(and SQLServer does sometimes but not always :-/ ) 
Writing is transactionally-controlled; no explicit write function.
Writing 
Objects that are registered and then changed are written 
•read in a unit of work = registered, otherwise register explicitly 
•#save: forces write, whether changed or not 
Process 
•inserts become updates when possible 
•RowMap is prepared, ordered (e.g. for foreign key constraints), written 
Performance 
•gets all sequence numbers at start of a transaction 
•prepared statements are cached, and arguments bound 
•inserts can use array binding, or statement grouping 
Instances <-> RowMap entries 
•Mementos allow rollback in image
2013 Cincom Systems, Inc. All Rights Reserved Developed in the U.S.A. CINCOM and the Quadrant Logo are registered trademarks of Cincom Systems, Inc. All other trademarks belong to their respective companies.
Contact info 
•Glorp 
nross@cincom.com Glorp team 
dwallen@cincom.com Glorp team 
trobinson@cincom.com Major internal customer 
•Star Team (Smalltalk Strategic Resources) 
sfortman@cincom.com Smalltalk Director 
athomas@cincom.com Smalltalk Product Manager 
jjordan@cincom.com Smalltalk Marketing Manager 
•http://www.cincomsmalltalk.com
The GLORP doctor is IN

More Related Content

What's hot

Javascript 101
Javascript 101Javascript 101
Javascript 101
Shlomi Komemi
 
Pxb For Yapc2008
Pxb For Yapc2008Pxb For Yapc2008
Pxb For Yapc2008
maximgrp
 
Drupal II: The SQL
Drupal II: The SQLDrupal II: The SQL
Drupal II: The SQL
ddiers
 
JavaScript Fundamentals & JQuery
JavaScript Fundamentals & JQueryJavaScript Fundamentals & JQuery
JavaScript Fundamentals & JQuery
Jamshid Hashimi
 
Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scala
scalaconfjp
 
JavaScript - Chapter 10 - Strings and Arrays
 JavaScript - Chapter 10 - Strings and Arrays JavaScript - Chapter 10 - Strings and Arrays
JavaScript - Chapter 10 - Strings and Arrays
WebStackAcademy
 
JavaScript - Chapter 4 - Types and Statements
 JavaScript - Chapter 4 - Types and Statements JavaScript - Chapter 4 - Types and Statements
JavaScript - Chapter 4 - Types and Statements
WebStackAcademy
 
Javascript
JavascriptJavascript
Javascript
Manav Prasad
 
JavaScript - Chapter 7 - Advanced Functions
 JavaScript - Chapter 7 - Advanced Functions JavaScript - Chapter 7 - Advanced Functions
JavaScript - Chapter 7 - Advanced Functions
WebStackAcademy
 
Javascript and Jquery Best practices
Javascript and Jquery Best practicesJavascript and Jquery Best practices
Javascript and Jquery Best practices
Sultan Khan
 
Lab #2: Introduction to Javascript
Lab #2: Introduction to JavascriptLab #2: Introduction to Javascript
Lab #2: Introduction to Javascript
Walid Ashraf
 
Extending the Xbase Typesystem
Extending the Xbase TypesystemExtending the Xbase Typesystem
Extending the Xbase Typesystem
Sebastian Zarnekow
 
JavaScript - Chapter 8 - Objects
 JavaScript - Chapter 8 - Objects JavaScript - Chapter 8 - Objects
JavaScript - Chapter 8 - Objects
WebStackAcademy
 
ORM in Django
ORM in DjangoORM in Django
ORM in Django
Hoang Nguyen
 
DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail
Laurent Dami
 
Django Pro ORM
Django Pro ORMDjango Pro ORM
Django Pro ORM
Alex Gaynor
 
Object Oriented PHP - PART-1
Object Oriented PHP - PART-1Object Oriented PHP - PART-1
Object Oriented PHP - PART-1
Jalpesh Vasa
 
Javascript
JavascriptJavascript
Javascript
guest03a6e6
 
Javascript
JavascriptJavascript
Javascript
Aditya Gaur
 
Javascript Journey
Javascript JourneyJavascript Journey
Javascript Journey
Wanqiang Ji
 

What's hot (20)

Javascript 101
Javascript 101Javascript 101
Javascript 101
 
Pxb For Yapc2008
Pxb For Yapc2008Pxb For Yapc2008
Pxb For Yapc2008
 
Drupal II: The SQL
Drupal II: The SQLDrupal II: The SQL
Drupal II: The SQL
 
JavaScript Fundamentals & JQuery
JavaScript Fundamentals & JQueryJavaScript Fundamentals & JQuery
JavaScript Fundamentals & JQuery
 
Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scala
 
JavaScript - Chapter 10 - Strings and Arrays
 JavaScript - Chapter 10 - Strings and Arrays JavaScript - Chapter 10 - Strings and Arrays
JavaScript - Chapter 10 - Strings and Arrays
 
JavaScript - Chapter 4 - Types and Statements
 JavaScript - Chapter 4 - Types and Statements JavaScript - Chapter 4 - Types and Statements
JavaScript - Chapter 4 - Types and Statements
 
Javascript
JavascriptJavascript
Javascript
 
JavaScript - Chapter 7 - Advanced Functions
 JavaScript - Chapter 7 - Advanced Functions JavaScript - Chapter 7 - Advanced Functions
JavaScript - Chapter 7 - Advanced Functions
 
Javascript and Jquery Best practices
Javascript and Jquery Best practicesJavascript and Jquery Best practices
Javascript and Jquery Best practices
 
Lab #2: Introduction to Javascript
Lab #2: Introduction to JavascriptLab #2: Introduction to Javascript
Lab #2: Introduction to Javascript
 
Extending the Xbase Typesystem
Extending the Xbase TypesystemExtending the Xbase Typesystem
Extending the Xbase Typesystem
 
JavaScript - Chapter 8 - Objects
 JavaScript - Chapter 8 - Objects JavaScript - Chapter 8 - Objects
JavaScript - Chapter 8 - Objects
 
ORM in Django
ORM in DjangoORM in Django
ORM in Django
 
DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail DBIx-DataModel v2.0 in detail
DBIx-DataModel v2.0 in detail
 
Django Pro ORM
Django Pro ORMDjango Pro ORM
Django Pro ORM
 
Object Oriented PHP - PART-1
Object Oriented PHP - PART-1Object Oriented PHP - PART-1
Object Oriented PHP - PART-1
 
Javascript
JavascriptJavascript
Javascript
 
Javascript
JavascriptJavascript
Javascript
 
Javascript Journey
Javascript JourneyJavascript Journey
Javascript Journey
 

Viewers also liked

Practically Using Glorp
Practically Using GlorpPractically Using Glorp
Practically Using Glorp
ESUG
 
Advanced O/R Mapping with Glorp
Advanced O/R Mapping with GlorpAdvanced O/R Mapping with Glorp
Advanced O/R Mapping with Glorp
ESUG
 
A Weak Pharo Story
A Weak Pharo StoryA Weak Pharo Story
A Weak Pharo Story
ESUG
 
GemStone/S 64bit
GemStone/S 64bitGemStone/S 64bit
GemStone/S 64bit
ESUG
 
Make the Past serve your Future
Make the Past serve your FutureMake the Past serve your Future
Make the Past serve your Future
ESUG
 
Store Beyond Glorp
Store Beyond GlorpStore Beyond Glorp
Store Beyond Glorp
ESUG
 
MongoTalk/Voyage
MongoTalk/VoyageMongoTalk/Voyage
MongoTalk/Voyage
ESUG
 
Object- Relational Persistence in Smalltalk
Object- Relational Persistence in SmalltalkObject- Relational Persistence in Smalltalk
Object- Relational Persistence in Smalltalk
ESUG
 
Tugrik: A new persistence option for Pharo
Tugrik: A new persistence option for PharoTugrik: A new persistence option for Pharo
Tugrik: A new persistence option for Pharo
ESUG
 
How and Where in GLORP
How and Where in GLORPHow and Where in GLORP
How and Where in GLORP
ESUG
 
Understanding Object Oriented Databases
Understanding Object Oriented Databases Understanding Object Oriented Databases
Understanding Object Oriented Databases
Objectivity
 

Viewers also liked (11)

Practically Using Glorp
Practically Using GlorpPractically Using Glorp
Practically Using Glorp
 
Advanced O/R Mapping with Glorp
Advanced O/R Mapping with GlorpAdvanced O/R Mapping with Glorp
Advanced O/R Mapping with Glorp
 
A Weak Pharo Story
A Weak Pharo StoryA Weak Pharo Story
A Weak Pharo Story
 
GemStone/S 64bit
GemStone/S 64bitGemStone/S 64bit
GemStone/S 64bit
 
Make the Past serve your Future
Make the Past serve your FutureMake the Past serve your Future
Make the Past serve your Future
 
Store Beyond Glorp
Store Beyond GlorpStore Beyond Glorp
Store Beyond Glorp
 
MongoTalk/Voyage
MongoTalk/VoyageMongoTalk/Voyage
MongoTalk/Voyage
 
Object- Relational Persistence in Smalltalk
Object- Relational Persistence in SmalltalkObject- Relational Persistence in Smalltalk
Object- Relational Persistence in Smalltalk
 
Tugrik: A new persistence option for Pharo
Tugrik: A new persistence option for PharoTugrik: A new persistence option for Pharo
Tugrik: A new persistence option for Pharo
 
How and Where in GLORP
How and Where in GLORPHow and Where in GLORP
How and Where in GLORP
 
Understanding Object Oriented Databases
Understanding Object Oriented Databases Understanding Object Oriented Databases
Understanding Object Oriented Databases
 

Similar to Glorp Tutorial Guide

Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard Wolff
JAX London
 
Scala and Spring
Scala and SpringScala and Spring
Scala and Spring
Eberhard Wolff
 
Oops lecture 1
Oops lecture 1Oops lecture 1
Oops lecture 1
rehan16091997
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemy
Inada Naoki
 
Rich Internet Applications con JavaFX e NetBeans
Rich Internet Applications  con JavaFX e NetBeans Rich Internet Applications  con JavaFX e NetBeans
Rich Internet Applications con JavaFX e NetBeans
Fabrizio Giudici
 
Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...
Andreas Dewes
 
Oracle Objects And Transactions
Oracle Objects And TransactionsOracle Objects And Transactions
Oracle Objects And Transactions
tepsum
 
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
Data Con LA
 
Meta Object Protocols
Meta Object ProtocolsMeta Object Protocols
Meta Object Protocols
Pierre de Lacaze
 
First class Variables in Pharo
First class Variables in PharoFirst class Variables in Pharo
First class Variables in Pharo
ESUG
 
Variables in Pharo5
Variables in Pharo5Variables in Pharo5
Variables in Pharo5
Marcus Denker
 
Code Cleanup: A Data Scientist's Guide to Sparkling Code
Code Cleanup: A Data Scientist's Guide to Sparkling CodeCode Cleanup: A Data Scientist's Guide to Sparkling Code
Code Cleanup: A Data Scientist's Guide to Sparkling Code
Corrie Bartelheimer
 
Lobos Introduction
Lobos IntroductionLobos Introduction
Lobos Introduction
Nicolas Buduroi
 
Rails Tips and Best Practices
Rails Tips and Best PracticesRails Tips and Best Practices
Rails Tips and Best Practices
David Keener
 
C# 7 development
C# 7 developmentC# 7 development
C# 7 development
Fisnik Doko
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord Migrations
Eleanor McHugh
 
Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987
乐群 陈
 
C# 101: Intro to Programming with C#
C# 101: Intro to Programming with C#C# 101: Intro to Programming with C#
C# 101: Intro to Programming with C#
Hawkman Academy
 
Spark Structured APIs
Spark Structured APIsSpark Structured APIs
Spark Structured APIs
Knoldus Inc.
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in Scala
Kazuhiro Sera
 

Similar to Glorp Tutorial Guide (20)

Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard Wolff
 
Scala and Spring
Scala and SpringScala and Spring
Scala and Spring
 
Oops lecture 1
Oops lecture 1Oops lecture 1
Oops lecture 1
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemy
 
Rich Internet Applications con JavaFX e NetBeans
Rich Internet Applications  con JavaFX e NetBeans Rich Internet Applications  con JavaFX e NetBeans
Rich Internet Applications con JavaFX e NetBeans
 
Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...
 
Oracle Objects And Transactions
Oracle Objects And TransactionsOracle Objects And Transactions
Oracle Objects And Transactions
 
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
 
Meta Object Protocols
Meta Object ProtocolsMeta Object Protocols
Meta Object Protocols
 
First class Variables in Pharo
First class Variables in PharoFirst class Variables in Pharo
First class Variables in Pharo
 
Variables in Pharo5
Variables in Pharo5Variables in Pharo5
Variables in Pharo5
 
Code Cleanup: A Data Scientist's Guide to Sparkling Code
Code Cleanup: A Data Scientist's Guide to Sparkling CodeCode Cleanup: A Data Scientist's Guide to Sparkling Code
Code Cleanup: A Data Scientist's Guide to Sparkling Code
 
Lobos Introduction
Lobos IntroductionLobos Introduction
Lobos Introduction
 
Rails Tips and Best Practices
Rails Tips and Best PracticesRails Tips and Best Practices
Rails Tips and Best Practices
 
C# 7 development
C# 7 developmentC# 7 development
C# 7 development
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord Migrations
 
Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987
 
C# 101: Intro to Programming with C#
C# 101: Intro to Programming with C#C# 101: Intro to Programming with C#
C# 101: Intro to Programming with C#
 
Spark Structured APIs
Spark Structured APIsSpark Structured APIs
Spark Structured APIs
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in Scala
 

More from ESUG

Workshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingWorkshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programming
ESUG
 
Technical documentation support in Pharo
Technical documentation support in PharoTechnical documentation support in Pharo
Technical documentation support in Pharo
ESUG
 
The Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapThe Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and Roadmap
ESUG
 
Sequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoSequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in Pharo
ESUG
 
Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...
ESUG
 
Analyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsAnalyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early results
ESUG
 
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
ESUG
 
A Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationA Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test Generation
ESUG
 
Creating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingCreating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic Programming
ESUG
 
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesThreaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
ESUG
 
Exploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportExploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience Report
ESUG
 
Pharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsPharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIs
ESUG
 
Garbage Collector Tuning
Garbage Collector TuningGarbage Collector Tuning
Garbage Collector Tuning
ESUG
 
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseImproving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
ESUG
 
Pharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FuturePharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and Future
ESUG
 
thisContext in the Debugger
thisContext in the DebuggerthisContext in the Debugger
thisContext in the Debugger
ESUG
 
Websockets for Fencing Score
Websockets for Fencing ScoreWebsockets for Fencing Score
Websockets for Fencing Score
ESUG
 
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScriptShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ESUG
 
Advanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocAdvanced Object- Oriented Design Mooc
Advanced Object- Oriented Design Mooc
ESUG
 
A New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and TransformationsA New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and Transformations
ESUG
 

More from ESUG (20)

Workshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingWorkshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programming
 
Technical documentation support in Pharo
Technical documentation support in PharoTechnical documentation support in Pharo
Technical documentation support in Pharo
 
The Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapThe Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and Roadmap
 
Sequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoSequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in Pharo
 
Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...
 
Analyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsAnalyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early results
 
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
 
A Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationA Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test Generation
 
Creating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingCreating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic Programming
 
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesThreaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
 
Exploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportExploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience Report
 
Pharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsPharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIs
 
Garbage Collector Tuning
Garbage Collector TuningGarbage Collector Tuning
Garbage Collector Tuning
 
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseImproving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
 
Pharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FuturePharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and Future
 
thisContext in the Debugger
thisContext in the DebuggerthisContext in the Debugger
thisContext in the Debugger
 
Websockets for Fencing Score
Websockets for Fencing ScoreWebsockets for Fencing Score
Websockets for Fencing Score
 
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScriptShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
 
Advanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocAdvanced Object- Oriented Design Mooc
Advanced Object- Oriented Design Mooc
 
A New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and TransformationsA New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and Transformations
 

Recently uploaded

zOS Mainframe JES2-JES3 JCL-JECL Differences
zOS Mainframe JES2-JES3 JCL-JECL DifferenceszOS Mainframe JES2-JES3 JCL-JECL Differences
zOS Mainframe JES2-JES3 JCL-JECL Differences
YousufSait3
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
Marcin Chrost
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
ToXSL Technologies
 
Mobile app Development Services | Drona Infotech
Mobile app Development Services  | Drona InfotechMobile app Development Services  | Drona Infotech
Mobile app Development Services | Drona Infotech
Drona Infotech
 
SQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure MalaysiaSQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure Malaysia
GohKiangHock
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
Yara Milbes
 
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
Peter Muessig
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
Top 9 Trends in Cybersecurity for 2024.pptx
Top 9 Trends in Cybersecurity for 2024.pptxTop 9 Trends in Cybersecurity for 2024.pptx
Top 9 Trends in Cybersecurity for 2024.pptx
devvsandy
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
mz5nrf0n
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
Green Software Development
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
ICS
 
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
XfilesPro
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
Ayan Halder
 
UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
Peter Muessig
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
mz5nrf0n
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
kalichargn70th171
 

Recently uploaded (20)

zOS Mainframe JES2-JES3 JCL-JECL Differences
zOS Mainframe JES2-JES3 JCL-JECL DifferenceszOS Mainframe JES2-JES3 JCL-JECL Differences
zOS Mainframe JES2-JES3 JCL-JECL Differences
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
 
Mobile app Development Services | Drona Infotech
Mobile app Development Services  | Drona InfotechMobile app Development Services  | Drona Infotech
Mobile app Development Services | Drona Infotech
 
SQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure MalaysiaSQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure Malaysia
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
 
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
Top 9 Trends in Cybersecurity for 2024.pptx
Top 9 Trends in Cybersecurity for 2024.pptxTop 9 Trends in Cybersecurity for 2024.pptx
Top 9 Trends in Cybersecurity for 2024.pptx
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
 
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
 
UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
 

Glorp Tutorial Guide

  • 1. 1 Welcome August 18, 2014 World Headquarters Cincinnati, Ohio How and Where in GLORP: GLORP Tutorial Reference Slides with Orange Titles: ESUG 2014 Tutorial. Slides with Blue Titles: additional GLORP info. Niall Ross, Cincom GLORP in Cincom® VisualWorks® (assist Cincom® ObjectStudio®)
  • 2. What is GLORP? •Generic: abstract, declarative, multi-platform f/w •Lightweight: looks like Smalltalk session read: Customer where: [:each | each orders size > 0] •Object: general hierarchic OO models no ActiveRecord-like style restriction remains flexible throughout the lifecycle •Relational: embedded or bound SQL •Persistence: transactions, constraints, indexes
  • 3. Glorp Documentation •GLORP is amazing GLORP’s documentation is less amazing  Nevin Pratt’s GlorpUserGuide0.3.pdf (in preview/glorp) (paraphrase) “Before displaying Glorp’s amazing power, I will summarise its raw rear end and show how that could be driven directly. … Having shown how an idiot would (mis)use GLORP, I will now TO BE COMPLETED.” Good summary of the DB-communicating lowest layer Roger Whitney’s GLORP Tutorial (www.eli.sdsu.edu/SmalltalkDocs/GlorpTutorial.pdf) Good course on basic, and some not so basic, things “beLockKey I have no idea what this does. “ •The greatest wisdom is to know what you don’t know Cincom VisualWorks GlorpGuide.pdf – good, getting-started coverage ObjectStudio MappingToolUsersGuide.pdf – great tool support And last, but not least …
  • 4. … my ESUG 2013 Talk •Walk-through GLORP (with demos) Architecture Mapping the domain model to the schema •initial generating / writing step •refining your mappings Queries Commit / Rollback •Focus on some less obvious aspects You can all read, and you can all #read: Follow-up sessions during the conference
  • 5. Example of using Glorp in VisualWorks •The Store workbook Is there anything your CM system isn’t telling you? Open the workbook, run the query | query | query := Query read: StoreBundle where: [:each || q | q := Query read: StoreBundle where: [:eachBundle | eachBundle name = each name]. q retrieve: [:x | x primaryKey max]. each username = 'aknight' & (each primaryKey = q)]. query orderBy: [:each | each timestamp descending]. session execute: query.
  • 6. GLORP Architecture Image Relational Database EXternal Database Interface GLORP GlorpSession UnitOfWork DatabaseAccessor ExternalDatabaseTransaction Transaction Domain Class GlorpClassModel Descriptor DescriptorSystem DatabaseTable DatabaseField DatabaseIndex DatabaseTableConstraint Mapping Join Table Column Index Constraint GlorpAttributeModel instvar
  • 7. Building GLORP Applications: mapping •getting started greenfields or legacy •write the GLORP and generate the schema into the DB and/or •auto-generate the GLORP mapping from an existing DB schema (ObjectStudio has powerful UI toolset to manage this Load ObjectStudio-prepared GLORP models in VisualWorks and/or (re)generate and refine GLORP models programmatically in VW but this talk will do everything programmatically in VisualWorks.) •refining / (re)creating in code make it run, make it right, make it fast
  • 8. Subclass DescriptorSystem to model … •those (parts of) Smalltalk classes to persist classModelFor<DomainClassName>: •the database tables you will write to and read from tableFor<TABLE_NAME>: •the mappings (“descriptors”) between the two descriptorFor<DomainClassName>: The GLORP f/w finds all the ...For<Name>: methods: creates parameter, names it, calls method with it
  • 9. Template: Class Model classModelFor<DomainClassName>: aClassModel aClassModel newAttributeNamed: #<instvar> type: <InstvarClass>. “e.g. String, Integer” ...
  • 10. Class models are simple •Annotate persisted parts of class with type information Set complex types (and simple if the mapping is tricky) aClassModel newAttributeNamed: #account type: Account. aClassModel newAttributeNamed: #name type: String. Set a collection class if you don’t want OrderedCollection aClassModel newAttributeNamed: #copies collection: Bag of: Book. •‘direct access’ (instVarAt:{put:} ) is the default To instead #perform: getters and setters, do (aClassModel newAttributeNamed: …) useDirectAccess: false. (can make it default for the whole descriptor system) N.B. the index is cached in DescriptorSystem instances
  • 11. Template: Table tableFor<TABLE_NAME>: aTable aTable createFieldNamed: ‘<column_name>’ type: platform <type>. “e.g. varchar: 255” ...
  • 12. Table models have more to them •Define the table’s fields / columns / attributes Set types from DatabasePlatform ‘type’ protocol aTable createFieldNamed: ‘id’ type: platform inMemorySequence. DatabaseField ‘configuring’ protocol •bePrimaryKey, beNullable:, isUnique:, beLockKey, defaultValue: Set foreign keys aTable addForeignKeyFrom: storeId to: (custTable fieldNamed: 'STORE_ID') from: custName to: (customerTable fieldNamed: 'CUSTOMERNAME') from: custDate to: (customerTable fieldNamed: 'BIRTHDATE'). Set indexes •beIndexed, addIndexForField:{and:{and:}}, addIndexForFields:
  • 13. Table models (2) •Image-only Keys, Imaginary Tables •foreignKey shouldCreateInDatabase: false “just for in-memory structuring” An object can map to less than one row •EmbeddedValueOneToOneMapping: target object is not stored in a separate table, but as part of the row of the containing object or to more/other than one row, e.g. •GROUP BY / DISTINCT rows in real table •specific fields from multiple tables •Some default values need to be platform-aware converter := booleanField converterForStType: Boolean. booleanField defaultValue: (converter convert: false toDatabaseRepresentationAs: booleanField type)
  • 14. Template: Descriptor descriptorFor<ClassName>: aDescriptor table := self tableNamed: ‘<TABLE_NAME>’. aDescriptor directMapping from: #<instvar> to: (table fieldNamed: ‘<column_name>’). ...
  • 15. Most of the complexity is in Descriptors •Each persistent class has a descriptor Most of its complexity is in its Mappings and their Joins •Descriptors pull together table(s) mappedFields mappings •and occasional stuff multipleTableJoin Cache policy, if different from system
  • 16. Descriptors: table-level mapping •Trivial: one class = one table, one instance = one row •Inheritance: HorizontalTypeResolver: one table per concrete subclass •target may need polymorphicJoin FilteredTypeResolver: sparse table with fields of all subclasses •General: Imaginary tables: embedded mappings, cross-table mappings DictionaryMapping: collection type that maps key as well as values ConditionalMapping, ConditionalToManyMapping •often employ a ConstantMapping as their ‘else’ outcome AdHocMapping
  • 17. Descriptors: field-level mapping •Mapping Types DirectMapping (DirectToManyMapping): mapping between (collections of) simple types such as Number, String, Boolean, and Timestamp. ToOneMapping: as direct, when target is a complex object. •EmbeddedValueOneToOneMapping: target object is not stored in a separate table, but rather as part of the row of the containing object ToManyMapping: #collectionType: •Mapping options •#beForPseudoVariable use in query, not in Smalltalk class, e.g. DatabaseField>>primaryKeyConstraints as an alias, e.g. id, not primaryKey •#shouldProxy: false “true is default”
  • 18. Template: Mapping with Join aDescriptor oneToOneMapping attrubuteName: #<name>; join: (Join from: (<table1> fieldNamed: ‘<columnA>’) to: (<table2> fieldNamed: ‘<columnB>’) …); ...
  • 19. Descriptors: field-level mapping - Joins Join is a utility class Join from: (table fieldNamed: ‘FKey’) to: (otherTable fieldNamed: ‘PKey’) from: … to: … from: … to: … •is both easier and safer than … join: [:each | (each foreignKey = other primaryKey) AND: …] •because general block expressions must fully define read and write, plus actually it is … join: [:other | other myEach …] “join expression from target” The mapping deduces as much as it can •referenceClass: join: useLinkTable linkTableJoin: targetTableJoin: •relevantLinkTableFields: - hints for the link table fields #beOuterJoin, #outerJoin: - false by default (and very usually) •whether left-side’s unjoined rows discarded or NULL-joined
  • 20. Parsing Mappings and Queries •The message eater (MessageArchiver) eats the block •N.B. avoid inlined selectors, e.g. use AND: or & •Messages in the block are mapped (in order) to Functions Mapped symbols: just #anySatisfy: and #select: Performed special selectors (Glorp internal or ST mimic) e.g. •#isEmpty #notEmpty #asDate #getTable: #getField: #fieldNamed: #parameter: #noneSatisfy: #getConstant: #count: #sum: #min: #max: #average: #sqlSelect: #includes: #aggregate:as: Named attributes Relationships
  • 21. Functions are easy to add •A basic list of generic functions, e.g at: #distinct put: (PrefixFunction named: 'DISTINCT'); at: #, put: (InfixFunction named: '||'); at: #between:and: put: (InfixFunction named: #('BETWEEN' 'AND')); at: #countStar put: (StandaloneFunction named: 'COUNT(*)'); at: #cast: put: ((Cast named: 'CAST') separator: ' AS '); •... is added to by specific subclasses, e.g. DB2Platform at: #days put: ((PostfixFunction named: 'DAYS') type: (self date)); enables this to work in DB2 as well where: [:each | each startDate + each daysToBonus days < Date today] (New feature: Date arithmetic is now better supported)
  • 22. Sort Order •#orderBy: isn't a sortblock. It defines the order field(s) query orderBy: #name ; orderBy: [:each | each address streetNumber descending]. •Lacking a suitable field, you can assign one mapping orderBy: (myTable fieldNamed: 'COLLECTION_ORDER'); writeTheOrderField. •Or you can sort in Smalltalk •anywhere you can specify a collection class, you can also use an instance query collectionType: (SortedCollection sortBlock: [:a :b | a isSuffixOf: b]). (N.B. if data read via a cursor, Smalltalk-side sorting is iffy)
  • 23. Template: Session Querying aClass := aGlorpSession readOneOf: <Class> where: aOneArgBlock. someClasses := aGlorpSession read: <Class> where: aOneArgBlock … (see GlorpSession protocol ‘api/queries’)
  • 24. Queries •The GlorpSession ‘api/queries’ protocol … session readOneOf: Book where: [:each | each title = ‘Persuasion’]. session read: Book where: [:each | each title like ‘Per%’] orderBy: #author. •… duplicates the API of Query class and subclasses in complex cases, configure Query then execute: previously divergent protocol now deprecated •use #read: not #readManyOf: or #returningManyOf: •Like Seaside, utility protocol plus cascades •#read:limit: #read:where:limit: #read:orderBy: #read:where:orderBy: #count: #count:where:
  • 25. Grouping by multiple criteria added Must not return conflicting values in any of the returned fields | books query | query := Query read: Book. query groupBy: [:each | each title]. query groupBy: [:each | each author]. query orderBy: [:each | each title]. query retrieve: [:each | each title]. query retrieve: [:each | each author]. query retrieve: [:each | each copiesInStock sum]. books := session execute: query. B/W-compatible API kept; a few changes made: •hasGroupBy -> hasGrouping •usesArrayBindingRatherThanGrouping -> usesArrayBindingRatherThanGroupWriting
  • 26. Query Performance: Reads Do as much on server as possible •use complex where clause •use CompoundQuery query1 unionAll: query2 query1 except: query2 Configure the query •#retrieve: gets less, #alsoFetch: gets more (also #shouldProxy: on mapping) •#expectedRows: preps caches Exploit database functions Use a cursor (not in PostgreSQL as yet) •query collectionType: GlorpCursoredStream GlorpVirtualCollection wraps a stream internally (size requires separate query)
  • 27. Query Performance: Reads (2) - DIY Prepare your own Glorp Command SQLStringSelectCommand new setSQLString: ‘select * from customers’. myCommand := SQLStringSelectCommand sqlString: 'SELECT id FROM books WHERE title=? AND author= ?’ parameters: #(‘Persuasion’ ‘Jane Austen’) “or use :param and a dictionary” useBinding: session useBinding session: session. and run it as a command query command: myCommand. session execute: query. or run it directly against the database session accessor executeCommand: myCommand
  • 28. Symbols, Blocks or Queries as params •#where:, #orderBy:, etc. take symbol, block or query cloneQuery := Query read: pundleClass where: [:each || othersQuery parentIdsQuery | parentIdsQuery := Query read: pundleClass where: [:e | e previous notNil]. parentIdsQuery retrieve: [:e | e previous id distinct]. parentIdsQuery collectionType: Set. othersQuery := Query read: pundleClass where: [:e | (e id ~= each id) & (e name = each name) & (e version = each version) & (e timestamp = each timestamp)]. (each timestamp < cutoffTimestamp) & (each exists: othersQuery) & (each id notIn: parentIdsQuery)]. cloneQuery collectionType: Bag. Performance sometimes needs all to be done on server.
  • 29. Invoke Functions via Expressions If you want a function to prefix a subselect … SELECT distinct A.methodRef FROM tw_methods A WHERE not exists (SELECT * FROM tw_methods B WHERE B.packageRef not in (25, 36) and A.methodRef = B.methodRef) and A.packageRef in (25, 36); … call it on the imported parameter packageIdsOfInterest := #(25 36). query := Query read: StoreMethodInPackage where: [:each | (each package id in: packageIdsOfInterest) AND: [each notExists: (Query read: StoreMethodInPackage where: [:mp | mp definition = each definition AND: [mp package id notIn: packageIdsOfInterest]])]]. query retrieve: [:each | each definition id distinct].
  • 30. Template: Session Writing session beginUnitOfWork; register: obj; “obj is a domain instance” commitUnitOfWork. session inUnitOfWorkDo: [session register: obj]. (see GlorpSession protocol ‘api/transactions’)
  • 31. Transaction (DB) v. UnitOfWork (Image) •Transaction: database maintains integrity via transactions, commits or rolls-back changes at transaction boundaries. The DatabaseAccessor holds the current transaction •UnitOfWork: holds changed objects and their unchanged priors, can roll-back Smalltalk-side changes in the image. The GlorpSession holds the current UnitOfWork •Users must manage (unavailable) nesting #inUnitOfWorkDo: defers to an outer UnitOfWork #beginUnitOfWork errors if called within an outer UnitOfWork (likewise for #inTransactionDo: versus #beginTransaction)
  • 32. Transaction v. UnitOfWork (2) •#transact: puts UnitOfWork inside Transaction, commits/rolls-back both, paired •#commitUnitOfWork (or #commitUnitOfWorkAndContinue) creates and commits a transaction if none is present does not commit if a transaction is present •#doDDLOperation: for table creation, deletion, alteration; some databases require a transaction in those cases, others do not •(and SQLServer does sometimes but not always :-/ ) Writing is transactionally-controlled; no explicit write function.
  • 33. Writing Objects that are registered and then changed are written •read in a unit of work = registered, otherwise register explicitly •#save: forces write, whether changed or not Process •inserts become updates when possible •RowMap is prepared, ordered (e.g. for foreign key constraints), written Performance •gets all sequence numbers at start of a transaction •prepared statements are cached, and arguments bound •inserts can use array binding, or statement grouping Instances <-> RowMap entries •Mementos allow rollback in image
  • 34. 2013 Cincom Systems, Inc. All Rights Reserved Developed in the U.S.A. CINCOM and the Quadrant Logo are registered trademarks of Cincom Systems, Inc. All other trademarks belong to their respective companies.
  • 35. Contact info •Glorp nross@cincom.com Glorp team dwallen@cincom.com Glorp team trobinson@cincom.com Major internal customer •Star Team (Smalltalk Strategic Resources) sfortman@cincom.com Smalltalk Director athomas@cincom.com Smalltalk Product Manager jjordan@cincom.com Smalltalk Marketing Manager •http://www.cincomsmalltalk.com