safe query objects: statically typed objects as remotely executable queries

22
Page 1 of 22 Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005 Department of Computer Sciences University of Texas at Austin

Upload: kalia-randall

Post on 30-Dec-2015

37 views

Category:

Documents


1 download

DESCRIPTION

Safe Query Objects: Statically Typed Objects as Remotely Executable Queries. By: William Cook & Siddhartha Rai ICSE 2005 Department of Computer Sciences University of Texas at Austin. Prerequisite #1: OpenJava. Pretends to be simple and universal Metaprogramming system - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 1 of 22

Safe Query Objects:Statically Typed Objects as Remotely Executable Queries

By: William Cook & Siddhartha RaiICSE 2005Department of Computer SciencesUniversity of Texas at Austin

Page 2: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 2 of 22

Prerequisite #1: OpenJava• Pretends to be simple and universal

Metaprogramming system– Compile time code generation: methods, properties etc.– The source is a kind of “pseudo-code”.– Examples for usefulness:

• Generous operator – like “…” in C or Vararg in Java 1.5• Can check for proper method overriding definitions

• Code generation is just text manipulation!• Problems in correctess, performance &

documentation• Had potential, but did not fly

Page 3: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 3 of 22

Prerequisite #2: JDO• Java Data Objects library for efficient persistence• What’s special?

– Stores and retrieves Java objects in a database– Objects are hierarchically structured and use

references– Database is typically relational – i.e. flat tables.

• JDO layer is absolutely transparent to the programmer– Takes care of object states – dirty, saved etc.– Need to define templates for DB tables as XML

metadata.

• The core of JDO is the PersistenceManager class

Page 4: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 4 of 22

Introduction

• Fact: Large Applications require persistence.

• Problems:– Code writing & maintenance– String encoding– Runtime checking only– Complex queries must be weaved by hand…– Programmers must learn two languages.

Page 5: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 5 of 22

New Idea

• Safe Query Objects– Working with relational database using

objects.– Represent a query as a statically typed object.– The same principle like in Ararat.

• We will see:– Statically typed interface to the dynamically

typed functionality in the JDO 1.0 specification.

Page 6: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 6 of 22

Instead of

class PerishablePrices {Integer lowerBound;boolean filter(Inventory item) {

return lowerBound == null|| item.Wholesale > lowerBound.intValue())&& (item.Type.Name.equals("fish")|| item.Type.Name.equals("meat");

}}

class PerishablePrices {Integer lowerBound;boolean filter(Inventory item) {

return lowerBound == null|| item.Wholesale > lowerBound.intValue())&& (item.Type.Name.equals("fish")|| item.Type.Name.equals("meat");

}}

Produce this:

SELECT '$' || (RETAIL/100) FROM INVENTORYWHERE WHOLESALE > parameter AND TYPE IN (SELECT TYPECODE,

TYPEDESC FROM TYPES WHERENAME = 'fish' OR NAME = 'meat')

SELECT '$' || (RETAIL/100) FROM INVENTORYWHERE WHOLESALE > parameter AND TYPE IN (SELECT TYPECODE,

TYPEDESC FROM TYPES WHERENAME = 'fish' OR NAME = 'meat')

Page 7: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 7 of 22

JDO Background: The Persistence Manager Interface

• Access to persistent objects via instance of the PersistenceManager interface.

• Loading individual objects:– getObjectById

• Creating a new Query:– newQuery

interface javax.jdo.PeristenceManager{Object getObjectById(Object id);Javax.jdo.Query newQuery(Class class);// methods for transactions not listed}

interface javax.jdo.PeristenceManager{Object getObjectById(Object id);Javax.jdo.Query newQuery(Class class);// methods for transactions not listed}

Page 8: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 8 of 22

JDO Background: The Query Interface

• Query execution is provided by the Query Interface.

interface javax.jdo.Query {void setFilter(String filter);void setOrdering(String ordering);void declareImports(String imports);void declareParameters(String params);void declareVariable(String vars);Object execute();Object execute(Object arg1);Object executeWithMap(Map parameters);// bookkeeping methods not listed

}

interface javax.jdo.Query {void setFilter(String filter);void setOrdering(String ordering);void declareImports(String imports);void declareParameters(String params);void declareVariable(String vars);Object execute();Object execute(Object arg1);Object executeWithMap(Map parameters);// bookkeeping methods not listed

}

Page 9: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 9 of 22

JDO Background:Candidate Classes

• Candidate classes:– Have structural correspondence to tables in database.

• We will use:

class Employee { String name; float salary; Department department; Employee manager;}

class Employee { String name; float salary; Department department; Employee manager;} class Department {

String name; Collection<Employee> employees;}

class Department { String name; Collection<Employee> employees;}

Page 10: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 10 of 22

JDO Background: Usage

Collection<Employee> execute(PersistenceManager pm){ javax.jdo.Query payCheck = pm.newQuery(Employee.class); payCheck.setFilter(“salary > maneger.salary”); Object result = payCheck.execute(); return (Collection<Employee>)result;}

Collection<Employee> execute(PersistenceManager pm){ javax.jdo.Query payCheck = pm.newQuery(Employee.class); payCheck.setFilter(“salary > maneger.salary”); Object result = payCheck.execute(); return (Collection<Employee>)result;}

The misspelled “maneger” will not be detected until runtime!Not type safe!

Page 11: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 11 of 22

Safe Query• Safe query object contains:

– Filtering method– Ordering method

• Safe Query Class– Subclass of SafeQuery<T>– Instantiates RemoteQueryJDO

class PayCheck extends SafeQuery<Employee> instantiates RemoteQueryJDO { boolean filter(Employee emp) {

return emp.salary > emp.maneger.salary; }}

class PayCheck extends SafeQuery<Employee> instantiates RemoteQueryJDO { boolean filter(Employee emp) {

return emp.salary > emp.maneger.salary; }}

Candidate Class

Compilation Error

Page 12: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 12 of 22

Safe query object suggested design

• Filtering Method:– Defines the “WHERE” condition in the query.– Must be called filter– Must return a boolean value.– Free of side effects:

• Must not modify states• No iterative constructs

No automaticchecks of proper

Design!

Not Clear!

Page 13: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 13 of 22

Sorted Results: JDO• Queries often specify sort order for the set of

query results.• Relational query languages:

– ascending/descending order.

• Sorting in JDO:– setOrdering method.

Collection sortEmployees() { javax.jdo.Query q = pm.newQuery(Employee.class); q.setOrdering(“department.name ascending,”

+ “ salary descending”); return (Collection) q.execute();}

Collection sortEmployees() { javax.jdo.Query q = pm.newQuery(Employee.class); q.setOrdering(“department.name ascending,”

+ “ salary descending”); return (Collection) q.execute();}

Page 14: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 14 of 22

Sorted Results: Safe Query

• Safe query defines order method– Takes a candidate object– Returns a linked list of sortable values.

class SortQuery instantiates RemoteQueryJDOextends SafeQuery<Employee> {

Sort order(Employee emp) { return new Sort(emp.department.name,

Sort.Direction.ASCENDING,new Sort(emp.salary,Sort.Direction.DESCENDING));

}}

class SortQuery instantiates RemoteQueryJDOextends SafeQuery<Employee> {

Sort order(Employee emp) { return new Sort(emp.department.name,

Sort.Direction.ASCENDING,new Sort(emp.salary,Sort.Direction.DESCENDING));

}}

Page 15: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 15 of 22

Parameterized Queries: JDO

• Needed when a query behavior depends upon one or more input value.

• JDO approach:– declareParameters method

Collection salaryLimitEmployees(double limit){ javax.jdo.Query q = pm.newQuery(Employee.class); q.setFilter(“salary > limit”); q.declareParameters(“Double limit”); Collection r = (Collection)q.execute(new Double(limit)); return r;}

Collection salaryLimitEmployees(double limit){ javax.jdo.Query q = pm.newQuery(Employee.class); q.setFilter(“salary > limit”); q.declareParameters(“Double limit”); Collection r = (Collection)q.execute(new Double(limit)); return r;} What happens if we omit the

call to declareParameters?

Page 16: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 16 of 22

Parameterized Queries: Safe Query

• Query parameters are defined as standard Java function parameters.

• Declared as arguments to the query constructor• Stored as member variables of the query object.

class SalaryLimit instantiates RemoteQueryJDOextends SafeQuery<Employee> {

double limit; /*parameter*/ SalaryLimit(double limit) {

this.limit = limit; } boolean filter(Employee employee) {

return employee.salary > limit; }}

class SalaryLimit instantiates RemoteQueryJDOextends SafeQuery<Employee> {

double limit; /*parameter*/ SalaryLimit(double limit) {

this.limit = limit; } boolean filter(Employee employee) {

return employee.salary > limit; }}

Page 17: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 17 of 22

Dynamic Queries: JDO• Involve filters, parameters or sort orders• Constructed at runtime.

Collection search(String namePrefix) { String filter = null; HashMap paramMap = new HashMap(); javax.jdo.Query q = makeQuery(Employee.class); if (namePrefix != null) { q.declareParameters(“String namePrefix”); paramMap.put(“namePrefix”,namePrefix); filter = ”(name.startsWith(namePrefix))”; } q.setFilter(filter); return q.executeWithMap(pramMap);}

Collection search(String namePrefix) { String filter = null; HashMap paramMap = new HashMap(); javax.jdo.Query q = makeQuery(Employee.class); if (namePrefix != null) { q.declareParameters(“String namePrefix”); paramMap.put(“namePrefix”,namePrefix); filter = ”(name.startsWith(namePrefix))”; } q.setFilter(filter); return q.executeWithMap(pramMap);}

No Type Safety!

Page 18: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 18 of 22

Dynamic Queries: Safe Query

class DynQuery instantiates RemoteQueryJDO extends SafeQuery<Employee> {

private String namePrefix; // may be nullprivate Double minSalary; // may be nullDynQuery (String namePrefix, Double minSalary){ this.namePrefix = namePrefix; this.minSalary = minSalary;}

boolean filter(Employee item) { return (namePrefix == null

|| item.name.startsWith(namePrefix)) && (minSalary == null

|| item.salary >= minSalary);}

}

class DynQuery instantiates RemoteQueryJDO extends SafeQuery<Employee> {

private String namePrefix; // may be nullprivate Double minSalary; // may be nullDynQuery (String namePrefix, Double minSalary){ this.namePrefix = namePrefix; this.minSalary = minSalary;}

boolean filter(Employee item) { return (namePrefix == null

|| item.name.startsWith(namePrefix)) && (minSalary == null

|| item.salary >= minSalary);}

}

Page 19: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 19 of 22

Implementation• The query translation is encapsulated in the RemoteQueryJDO metaclass which is applied to the safe query by the OpenJava instantiates keyword.

• OpenJava runs the metaclass at compile time, supplying the definition of the of the query class (e.g. PayCheck) as input.

• The RemoteQueryJDO metaclass examines the user-defined filter method and generates the corresponding execute method.

Page 20: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 20 of 22

OpenJava

RemoteQueryJDOMetaclass

Query Class Definition

Execute Method

Compile Time

Page 21: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 21 of 22

Advantages

• Queries defined using OO language– Static type checking– Syntax errors (at compilation time)– JDO seems more comfortable

• Observation: Most queries are either static or dynamic with static tables.– Safe query can help.

Page 22: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

Page 22 of 22

Disadvantages

• Dynamic queries and data-driven with query definition loaded from DB– Open problem…

• What about creating new tables?

• Updating tables..