SlideShare uma empresa Scribd logo
1 de 30
Baixar para ler offline
1
Welcome
September 30, 2013
World Headquarters
Cincinnati, Ohio
How and Where in GLORP
How to use the GLORP framework. Where to
find specific functionality. Points to know.
Niall Ross
GLORP in Cincom® VisualWorks®
(assist Cincom® ObjectStudio®)
The GLORP Project
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
Why this talk?
• 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
What will this Talk cover?
• 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:
At the end of this talk, the GLORP doctors are IN !!
Before we start, a taste of using Glorp
• 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<ClassName>:
• The database tables you will write to and read from
 tableFor<TABLE_NAME>:
• The mappings (“descriptors”) between the two
 descriptorFor<ClassName>:
Refactorings now respect embedded classnames [Demo]
(ongoing work is enhancing flexibility / refactoring)
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
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)
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”
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)
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
• #read: not #readManyOf: , #read…: not #returning…:
• 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].
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 doctors are IN

Mais conteúdo relacionado

Mais procurados

NoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryNoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryAlexandre Morgaut
 
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018Sunghyouk Bae
 
Hector v2: The Second Version of the Popular High-Level Java Client for Apach...
Hector v2: The Second Version of the Popular High-Level Java Client for Apach...Hector v2: The Second Version of the Popular High-Level Java Client for Apach...
Hector v2: The Second Version of the Popular High-Level Java Client for Apach...zznate
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Sunghyouk Bae
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not JavaChris Adamson
 
User defined-functions-cassandra-summit-eu-2014
User defined-functions-cassandra-summit-eu-2014User defined-functions-cassandra-summit-eu-2014
User defined-functions-cassandra-summit-eu-2014Robert Stupp
 
April 2010 - JBoss Web Services
April 2010 - JBoss Web ServicesApril 2010 - JBoss Web Services
April 2010 - JBoss Web ServicesJBug Italy
 
JUnit5 and TestContainers
JUnit5 and TestContainersJUnit5 and TestContainers
JUnit5 and TestContainersSunghyouk Bae
 
MongoDB 在盛大大数据量下的应用
MongoDB 在盛大大数据量下的应用MongoDB 在盛大大数据量下的应用
MongoDB 在盛大大数据量下的应用iammutex
 
Infinispan,Lucene,Hibername OGM
Infinispan,Lucene,Hibername OGMInfinispan,Lucene,Hibername OGM
Infinispan,Lucene,Hibername OGMJBug Italy
 
Meetup cassandra sfo_jdbc
Meetup cassandra sfo_jdbcMeetup cassandra sfo_jdbc
Meetup cassandra sfo_jdbczznate
 
Getting started with Clojure
Getting started with ClojureGetting started with Clojure
Getting started with ClojureJohn Stevenson
 
Cassandra 3.0 Awesomeness
Cassandra 3.0 AwesomenessCassandra 3.0 Awesomeness
Cassandra 3.0 AwesomenessJon Haddad
 
Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access Rebecca Grenier
 

Mais procurados (20)

NoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryNoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love Story
 
XQuery in the Cloud
XQuery in the CloudXQuery in the Cloud
XQuery in the Cloud
 
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
 
Hector v2: The Second Version of the Popular High-Level Java Client for Apach...
Hector v2: The Second Version of the Popular High-Level Java Client for Apach...Hector v2: The Second Version of the Popular High-Level Java Client for Apach...
Hector v2: The Second Version of the Popular High-Level Java Client for Apach...
 
XQuery Design Patterns
XQuery Design PatternsXQuery Design Patterns
XQuery Design Patterns
 
Cassandra 3.0
Cassandra 3.0Cassandra 3.0
Cassandra 3.0
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not Java
 
User defined-functions-cassandra-summit-eu-2014
User defined-functions-cassandra-summit-eu-2014User defined-functions-cassandra-summit-eu-2014
User defined-functions-cassandra-summit-eu-2014
 
April 2010 - JBoss Web Services
April 2010 - JBoss Web ServicesApril 2010 - JBoss Web Services
April 2010 - JBoss Web Services
 
JUnit5 and TestContainers
JUnit5 and TestContainersJUnit5 and TestContainers
JUnit5 and TestContainers
 
MongoDB 在盛大大数据量下的应用
MongoDB 在盛大大数据量下的应用MongoDB 在盛大大数据量下的应用
MongoDB 在盛大大数据量下的应用
 
Infinispan,Lucene,Hibername OGM
Infinispan,Lucene,Hibername OGMInfinispan,Lucene,Hibername OGM
Infinispan,Lucene,Hibername OGM
 
Meetup cassandra sfo_jdbc
Meetup cassandra sfo_jdbcMeetup cassandra sfo_jdbc
Meetup cassandra sfo_jdbc
 
Getting started with Clojure
Getting started with ClojureGetting started with Clojure
Getting started with Clojure
 
Slickdemo
SlickdemoSlickdemo
Slickdemo
 
Cassandra 3.0 Awesomeness
Cassandra 3.0 AwesomenessCassandra 3.0 Awesomeness
Cassandra 3.0 Awesomeness
 
Linq
LinqLinq
Linq
 
wtf is in Java/JDK/wtf7?
wtf is in Java/JDK/wtf7?wtf is in Java/JDK/wtf7?
wtf is in Java/JDK/wtf7?
 
Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access Slick: Bringing Scala’s Powerful Features to Your Database Access
Slick: Bringing Scala’s Powerful Features to Your Database Access
 

Semelhante a How and Where in GLORP

Glorp Tutorial Guide
Glorp Tutorial GuideGlorp Tutorial Guide
Glorp Tutorial GuideESUG
 
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 WolffJAX London
 
Awesome html with ujs, jQuery and coffeescript
Awesome html with ujs, jQuery and coffeescriptAwesome html with ujs, jQuery and coffeescript
Awesome html with ujs, jQuery and coffeescriptAmir Barylko
 
JSLT: JSON querying and transformation
JSLT: JSON querying and transformationJSLT: JSON querying and transformation
JSLT: JSON querying and transformationLars Marius Garshol
 
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
 
[OOP - Lec 13,14,15] Constructors / Destructor and its Types
[OOP - Lec 13,14,15] Constructors / Destructor and its Types[OOP - Lec 13,14,15] Constructors / Destructor and its Types
[OOP - Lec 13,14,15] Constructors / Destructor and its TypesMuhammad Hammad Waseem
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemyInada Naoki
 
Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']Jan Helke
 
Hi performance table views with QuartzCore and CoreText
Hi performance table views with QuartzCore and CoreTextHi performance table views with QuartzCore and CoreText
Hi performance table views with QuartzCore and CoreTextMugunth Kumar
 
Cappuccino - A Javascript Application Framework
Cappuccino - A Javascript Application FrameworkCappuccino - A Javascript Application Framework
Cappuccino - A Javascript Application FrameworkAndreas Korth
 
Spark Structured APIs
Spark Structured APIsSpark Structured APIs
Spark Structured APIsKnoldus Inc.
 
Look Mommy, No GC! (TechDays NL 2017)
Look Mommy, No GC! (TechDays NL 2017)Look Mommy, No GC! (TechDays NL 2017)
Look Mommy, No GC! (TechDays NL 2017)Dina Goldshtein
 
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami
 
Swift Micro-services and AWS Technologies
Swift Micro-services and AWS TechnologiesSwift Micro-services and AWS Technologies
Swift Micro-services and AWS TechnologiesSimonPilkington8
 
Entity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic UnicornsEntity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic UnicornsRichie Rump
 
iOS 2 - The practical Stuff
iOS 2 - The practical StuffiOS 2 - The practical Stuff
iOS 2 - The practical StuffPetr Dvorak
 
C# 7 development
C# 7 developmentC# 7 development
C# 7 developmentFisnik Doko
 

Semelhante a How and Where in GLORP (20)

Glorp Tutorial Guide
Glorp Tutorial GuideGlorp Tutorial Guide
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
 
Scala and Spring
Scala and SpringScala and Spring
Scala and Spring
 
Oops lecture 1
Oops lecture 1Oops lecture 1
Oops lecture 1
 
Awesome html with ujs, jQuery and coffeescript
Awesome html with ujs, jQuery and coffeescriptAwesome html with ujs, jQuery and coffeescript
Awesome html with ujs, jQuery and coffeescript
 
JSLT: JSON querying and transformation
JSLT: JSON querying and transformationJSLT: JSON querying and transformation
JSLT: JSON querying and transformation
 
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
 
[OOP - Lec 13,14,15] Constructors / Destructor and its Types
[OOP - Lec 13,14,15] Constructors / Destructor and its Types[OOP - Lec 13,14,15] Constructors / Destructor and its Types
[OOP - Lec 13,14,15] Constructors / Destructor and its Types
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemy
 
Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']
 
Hi performance table views with QuartzCore and CoreText
Hi performance table views with QuartzCore and CoreTextHi performance table views with QuartzCore and CoreText
Hi performance table views with QuartzCore and CoreText
 
Cappuccino - A Javascript Application Framework
Cappuccino - A Javascript Application FrameworkCappuccino - A Javascript Application Framework
Cappuccino - A Javascript Application Framework
 
Spark Structured APIs
Spark Structured APIsSpark Structured APIs
Spark Structured APIs
 
Look Mommy, No GC! (TechDays NL 2017)
Look Mommy, No GC! (TechDays NL 2017)Look Mommy, No GC! (TechDays NL 2017)
Look Mommy, No GC! (TechDays NL 2017)
 
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
 
Swift Micro-services and AWS Technologies
Swift Micro-services and AWS TechnologiesSwift Micro-services and AWS Technologies
Swift Micro-services and AWS Technologies
 
Entity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic UnicornsEntity Framework: Code First and Magic Unicorns
Entity Framework: Code First and Magic Unicorns
 
XAML/C# to HTML/JS
XAML/C# to HTML/JSXAML/C# to HTML/JS
XAML/C# to HTML/JS
 
iOS 2 - The practical Stuff
iOS 2 - The practical StuffiOS 2 - The practical Stuff
iOS 2 - The practical Stuff
 
C# 7 development
C# 7 developmentC# 7 development
C# 7 development
 

Mais de 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 programmingESUG
 
Technical documentation support in Pharo
Technical documentation support in PharoTechnical documentation support in Pharo
Technical documentation support in PharoESUG
 
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 RoadmapESUG
 
Sequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoSequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoESUG
 
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 resultsESUG
 
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 6ESUG
 
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 GenerationESUG
 
Creating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingCreating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingESUG
 
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 ModesESUG
 
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 ReportESUG
 
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 APIsESUG
 
Garbage Collector Tuning
Garbage Collector TuningGarbage Collector Tuning
Garbage Collector TuningESUG
 
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 CaseESUG
 
Pharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FuturePharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FutureESUG
 
thisContext in the Debugger
thisContext in the DebuggerthisContext in the Debugger
thisContext in the DebuggerESUG
 
Websockets for Fencing Score
Websockets for Fencing ScoreWebsockets for Fencing Score
Websockets for Fencing ScoreESUG
 
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 JavaScriptESUG
 
Advanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocAdvanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocESUG
 
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 TransformationsESUG
 

Mais de 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
 

Último

Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 

Último (20)

Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 

How and Where in GLORP

  • 1. 1 Welcome September 30, 2013 World Headquarters Cincinnati, Ohio How and Where in GLORP How to use the GLORP framework. Where to find specific functionality. Points to know. Niall Ross GLORP in Cincom® VisualWorks® (assist Cincom® ObjectStudio®) The GLORP Project
  • 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. Why this talk? • 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
  • 4. What will this Talk cover? • 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: At the end of this talk, the GLORP doctors are IN !!
  • 5. Before we start, a taste of using Glorp • 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<ClassName>: • The database tables you will write to and read from  tableFor<TABLE_NAME>: • The mappings (“descriptors”) between the two  descriptorFor<ClassName>: Refactorings now respect embedded classnames [Demo] (ongoing work is enhancing flexibility / refactoring)
  • 9. 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
  • 10. 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:
  • 11. 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)
  • 12. 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
  • 13. 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
  • 14. 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”
  • 15. 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
  • 16. 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
  • 17. 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)
  • 18. 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)
  • 19. 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 • #read: not #readManyOf: , #read…: not #returning…: • Like Seaside, utility protocol plus cascades • #read:limit: #read:where:limit: #read:orderBy: #read:where:orderBy: #count: #count:where:
  • 20. 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
  • 21. 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)
  • 22. 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
  • 23. 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.
  • 24. 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].
  • 25. 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)
  • 26. 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.
  • 27. 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
  • 28. 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.
  • 29. 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