You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-commits@db.apache.org by an...@apache.org on 2022/04/13 14:19:09 UTC

[db-jdo-site] branch main updated: Change to JDO 3.2 javadocs links. Remove extents doc since already part of object retrieval. Copy query_api doc from DN docs, removing DN-specific parts.

This is an automated email from the ASF dual-hosted git repository.

andyj pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/db-jdo-site.git


The following commit(s) were added to refs/heads/main by this push:
     new 3981aa6  Change to JDO 3.2 javadocs links. Remove extents doc since already part of object retrieval. Copy query_api doc from DN docs, removing DN-specific parts.
3981aa6 is described below

commit 3981aa68583132f75760ac7637a21bf7f3aace14
Author: andyjefferson <an...@datanucleus.org>
AuthorDate: Wed Apr 13 15:19:03 2022 +0100

    Change to JDO 3.2 javadocs links.
    Remove extents doc since already part of object retrieval.
    Copy query_api doc from DN docs, removing DN-specific parts.
---
 src/main/asciidoc/extents.adoc          |  29 ---
 src/main/asciidoc/fetchgroups.adoc      |   2 +-
 src/main/asciidoc/jdohelper.adoc        |   2 +-
 src/main/asciidoc/jdoql.adoc            | 170 ++++++++------
 src/main/asciidoc/jdoql_methods.adoc    |  28 ++-
 src/main/asciidoc/jdoql_result.adoc     |  87 ++++---
 src/main/asciidoc/object_retrieval.adoc |  66 +++---
 src/main/asciidoc/pm.adoc               |   2 +-
 src/main/asciidoc/pmf.adoc              |   2 +-
 src/main/asciidoc/query_api.adoc        | 399 ++++++++++++++++++++++++++++++++
 src/main/template/document.html.erb     |   6 +-
 11 files changed, 604 insertions(+), 189 deletions(-)

diff --git a/src/main/asciidoc/extents.adoc b/src/main/asciidoc/extents.adoc
deleted file mode 100644
index a8422ed..0000000
--- a/src/main/asciidoc/extents.adoc
+++ /dev/null
@@ -1,29 +0,0 @@
-:_basedir: 
-:_imagesdir: images/
-:notoc:
-:notitle:
-:grid: cols
-:query:
-
-[[index]]
-
-== JDO Extentsanchor:JDO_Extents[]
-
-JDO implementations manage the persistence of objects into the
-datastore. An *Extent* is a collection of objects of a particular type
-of object that have been persisted. When you define the MetaData for a
-class you can define if the class requires an Extent. The default is
-true. You access the Extent as follows
-
-....
-Extent e = pm.getExtent(MyClass.class, true);
-            
-....
-
-This example will return an Extent that contains all persisted instances
-of the class _MyClass_ and its subclasses (the second argument in the
-call). An Extent is useful where you want to restrict a Query to query
-over just that set of objects. It can also be used where you just want
-to retrieve all persisted objects of a type (as an alternative to using
-a Query).
-
diff --git a/src/main/asciidoc/fetchgroups.adoc b/src/main/asciidoc/fetchgroups.adoc
index e96ffd2..de6f573 100644
--- a/src/main/asciidoc/fetchgroups.adoc
+++ b/src/main/asciidoc/fetchgroups.adoc
@@ -24,7 +24,7 @@ that are part of that fetch group. The definition here is _static_
 groups at runtime via an API
 
 The *fetch group* in use for a class is controled via the _FetchPlan_
-http://db.apache.org/jdo/api20/apidocs/javax/jdo/FetchPlan.html[image:images/javadoc.png[image]]
+http://db.apache.org/jdo/api32/apidocs/javax/jdo/FetchPlan.html[image:images/javadoc.png[image]]
 interface. To get a handle on the current _FetchPlan_ we do
 
 ....
diff --git a/src/main/asciidoc/jdohelper.adoc b/src/main/asciidoc/jdohelper.adoc
index 06d776b..4c93589 100644
--- a/src/main/asciidoc/jdohelper.adoc
+++ b/src/main/asciidoc/jdohelper.adoc
@@ -10,7 +10,7 @@
 JDO provides a standard utility that gives access to useful parts of the
 JDO persistence process. This is known as *JDOHelper*
 (javax.jdo.JDOHelper)
-link:api20/apidocs/javax/jdo/JDOHelper.html[image:images/javadoc.png[image]]
+link:api32/apidocs/javax/jdo/JDOHelper.html[image:images/javadoc.png[image]]
 
 === PersistenceManagerFactory methodsanchor:PersistenceManagerFactory_methods[]
 
diff --git a/src/main/asciidoc/jdoql.adoc b/src/main/asciidoc/jdoql.adoc
index d8cd6e9..2da77cc 100644
--- a/src/main/asciidoc/jdoql.adoc
+++ b/src/main/asciidoc/jdoql.adoc
@@ -5,50 +5,49 @@
 
 [[index]]
 
-== JDOQLanchor:JDOQL[]
+[[JDOQL]]
+== JDOQL
 
-JDO defines ways of querying objects persisted into the datastore. It
-provides its own object-based query language (JDOQL). JDOQL is designed
-as the Java developers way of having the power of SQL queries, yet
-retaining the Java object relationship that exist in their application
-model. A typical JDOQL query may be set up in one of 2 ways. Here's an
-example
+JDO defines ways of querying objects persisted into the datastore. 
+It provides its own object-based query language (JDOQL). 
+JDOQL is designed as the Java developers way of having the power of SQL queries, yet retaining the Java object relationship that exist in their application model. 
+A typical JDOQL query may be set up in one of 2 ways. Here's an example.
 
-....
 Declarative JDOQL :
+
+[source,java]
+....
 Query q = pm.newQuery(mydomain.Person.class, "lastName == \"Jones\" && age < age_limit");
 q.declareParameters("double age_limit");
 List results = (List)q.execute(20.0);
+....
 
 Single-String JDOQL :
+
+[source,java]
+....
 Query q = pm.newQuery("SELECT FROM mydomain.Person WHERE lastName == \"Jones\"" +
                       " && age < :age_limit PARAMETERS double age_limit");
 List results = (List)q.execute(20.0);
 ....
 
-So here in our example we select all "Person" objects with surname of
-"Jones" and where the persons age is below 20. The language is intuitive
-for Java developers, and is intended as their interface to accessing the
-persisted data model. As can be seen above, the query is made up of
-distinct parts. The class being selected (the SELECT clause in SQL), the
-filter (which equates to the WHERE clause in SQL), together with any
-sorting (the ORDER BY clause in SQL), etc.
+So here in our example we select all "Person" objects with surname of "Jones" and where the persons age is below 20. 
+The language is intuitive for Java developers, and is intended as their interface to accessing the persisted data model. 
+As can be seen above, the query is made up of distinct parts. 
+The class being selected (the SELECT clause in SQL), the filter (which equates to the WHERE clause in SQL), 
+together with any sorting (the ORDER BY clause in SQL), etc.
 
-Before giving details on JDOQL, you can download a quick reference guide
-link:jdoql_quickref.pdf[here]
+Before giving details on JDOQL, you can download a quick reference guide link:jdoql_quickref.pdf[here]
 
-{empty} +
 
-anchor:singlestring[]
 
-=== Single-String JDOQLanchor:Single-String_JDOQL[]
+[[singlestring]]
+=== Single-String JDOQL
 
-In traditional (declarative) JDOQL (JDO 1.0) it was necessary to specify
-the component parts (filter, candidate class, ordering, etc) of the
-query using the mutator methods on the Query. In JDO 2 you can now
-specify it all in a single string. This string has to follow a
-particular pattern, but provides the convenience that many people have
-been asking for. The pattern to use is as follows
+In original (declarative) JDOQL (JDO 1.0) it was necessary to specify the component parts (filter, candidate class, ordering, etc) 
+of the query using the mutator methods on the Query. From JDO 2 onwards you can specify it all in a single string. 
+This string has to follow a particular pattern, but provides the convenience that many people require. 
+The pattern to use is as follows
 
 ....
 SELECT [UNIQUE] [<result>] [INTO <result-class>]
@@ -62,8 +61,7 @@ SELECT [UNIQUE] [<result>] [INTO <result-class>]
         [RANGE <start>, <end>]
 ....
 
-The "keywords" in the query are shown in UPPER CASE but can be in
-_UPPER_ or _lower_ case.
+The "keywords" in the query are shown in UPPER CASE but can be in _UPPER_ or _lower_ case.
 
 Lets give an example of a query using this syntax
 
@@ -71,39 +69,41 @@ Lets give an example of a query using this syntax
 SELECT UNIQUE FROM org.datanucleus.samples.Employee ORDER BY departmentNumber
 ....
 
-so we form the parts of the query as before, yet here we just specify it
-all in a single call.
+so we form the parts of the query as before, yet here we just specify it all in a single call.
+
+
 
-=== Accessing Fieldsanchor:Accessing_Fields[]
+[[Accessing_Fields]]
+=== Accessing Fields
 
 In JDOQL you access fields in the query by referring to the field name.
-For example, if you are querying a class called _Product_ and it has a
-field "price", then you access it like this
+For example, if you are querying a class called _Product_ and it has a field "price", then you access it like this
 
+[source,java]
 ....
 Query query = pm.newQuery(mydomain.Product.class, "price < 150.0");
 ....
 
-In addition to the persistent fields, you can also access "public static
-final" fields of any class. You can do this as follows
+In addition to the persistent fields, you can also access "public static final" fields of any class. You can do this as follows
 
+[source,java]
 ....
-Query query = pm.newQuery(mydomain.Product.class, 
-       "taxPercent < mydomain.Product.TAX_BAND_A");
+Query query = pm.newQuery(mydomain.Product.class, "taxPercent < mydomain.Product.TAX_BAND_A");
 ....
 
-So this will find all products that include a tax percentage less than
-some "BAND A" level. Where you are using "public static final" fields
-you can either fully-qualify the class name or you can include it in the
+So this will find all products that include a tax percentage less than some "BAND A" level. 
+Where you are using "public static final" fields you can either fully-qualify the class name or you can include it in the
 "imports" section of the query (see later).
 
-=== Data types : literalsanchor:Data_types_:_literals[]
 
-JDOQL supports the following literals: IntegerLiteral,
-FloatingPointLiteral, BooleanLiteral, CharacterLiteral, StringLiteral,
-and NullLiteral.
+[[Data_types_:_literals]]
+=== Data types : literals
+
+JDOQL supports the following literals: IntegerLiteral, FloatingPointLiteral, BooleanLiteral, CharacterLiteral, StringLiteral, and NullLiteral.
+
 
-=== Operators precedenceanchor:Operators_precedence[]
+[[Operators_precedence]]
+=== Operators precedence
 
 The following list describes the operator precedence in JDOQL.
 
@@ -120,26 +120,34 @@ The following list describes the operator precedence in JDOQL.
 . Conditional AND ("&&")
 . Conditional OR ("||")
 
-=== Concatenation Expressionsanchor:Concatenation_Expressions[]
 
-The concatenation operator(+) concatenates a String to either another
-String or Number. Concatenations of String or Numbers to null results in
-null.
+[[Concatenation_Expressions]]
+=== Concatenation Expressions
 
-=== Example 1 - Use of Explicit Parametersanchor:Example_1_-_Use_of_Explicit_Parameters[]
+The concatenation operator(+) concatenates a String to either another String or Number. 
+Concatenations of String or Numbers to null results in null.
 
-Here's a simple example for finding the elements of a class with a field
-below a particular threshold level. Here we pass in the threshold value
-(_limit_), and sort the output in order of ascending price.
 
-....
+[[Example_1_-_Use_of_Explicit_Parameters]]
+=== Example 1 - Use of Explicit Parameters
+
+Here's a simple example for finding the elements of a class with a field below a particular threshold level. 
+Here we pass in the threshold value (_limit_), and sort the output in order of ascending price.
+
 Declarative JDOQL :
+
+[source,java]
+....
 Query query = pm.newQuery(mydomain.Product.class,"price < limit");
 query.declareParameters("double limit");
 query.setOrdering("price ascending");
 List results = (List)query.execute(150.00);
+....
 
 Single-String JDOQL :
+
+[source,java]
+....
 Query query = pm.newQuery("SELECT FROM mydomain.Product WHERE " +
                 "price < limit PARAMETERS double limit ORDER BY price ASCENDING");
 List results = (List)query.execute(150.00);
@@ -147,6 +155,7 @@ List results = (List)query.execute(150.00);
 
 For completeness, the class is shown here
 
+[source,java]
 ....
 class Product
 {
@@ -155,7 +164,10 @@ class Product
     java.util.Date endDate;
     ...
 }
+....
 
+[source,xml]
+....
 <jdo>
     <package name="mydomain">
         <class name="Product">
@@ -175,46 +187,56 @@ class Product
 {empty} +
 
 
-=== Example 2 - Use of Implicit Parametersanchor:Example_2_-_Use_of_Implicit_Parameters[]
+[[Example_2_-_Use_of_Implicit_Parameters]]
+=== Example 2 - Use of Implicit Parameters
 
-Let's repeat the previous query but this time using _implicit_
-parameters.
+Let's repeat the previous query but this time using _implicit_ parameters.
 
-....
 Declarative JDOQL :
+
+[source,java]
+....
 Query query = pm.newQuery(mydomain.Product.class,"price < :limit");
 query.setOrdering("price ascending");
 List results = (List)query.execute(150.00);
+....
 
 Single-String JDOQL :
+
+[source,java]
+....
 Query query = pm.newQuery("SELECT FROM mydomain.Product WHERE " +
                 "price < :limit ORDER BY price ASCENDING");
 List results = (List)query.execute(150.00);
 ....
 
-So we omitted the declaration of the parameter and just prefixed it with
-a colon (:)
-
-{empty} +
+So we omitted the declaration of the parameter and just prefixed it with a colon (:).
 
 
-=== Example 3 - Comparison against Datesanchor:Example_3_-_Comparison_against_Dates[]
+[[Example_3_-_Comparison_against_Dates]]
+=== Example 3 - Comparison against Dates
 
 Here's another example using the same Product class as above, but this
 time comparing to a Date field. Because we are using a type in our
 query, we need to _import_ it ... just like you would in a Java class if
 you were using it there.
 
-....
 Declarative JDOQL :
+
+[source,java]
+....
 Query query = pm.newQuery(domain.Product.class,
                           "endDate > best_before_limit");
 query.declareImports("import java.util.Date");
 query.declareParameters("Date best_before_limit");
 query.setOrdering("endDate descending");
 Collection results = (Collection)query.execute(my_date_limit);
+....
 
 Single-String JDOQL :
+
+[source,java]
+....
 Query query = pm.newQuery("SELECT FROM mydomain.Product " +
                 "WHERE endDate > best_before_limit " +
                 "PARAMETERS Date best_before_limit " +
@@ -222,24 +244,28 @@ Query query = pm.newQuery("SELECT FROM mydomain.Product " +
 List results = (List)query.execute(my_date_limit);
 ....
 
-{empty} +
 
+[[Example_4_-_Instanceof]]
+=== Example 4 - Instanceof
 
-=== Example 4 - Instanceofanchor:Example_4_-_Instanceof[]
+This example demonstrates use of the "instanceof" operator. 
+We have a class A that has a field "b" of type B and B has subclasses B1, B2, B3.
+Clearly the field "b" of A can be of type B, B1, B2, B3 etc, and we want to find all objects of type A that have the field "b" that is of type B2. 
+We do it like this
 
-This example demonstrates use of the "instanceof" operator. We have a
-class A that has a field "b" of type B and B has subclasses B1, B2, B3.
-Clearly the field "b" of A can be of type B, B1, B2, B3 etc, and we want
-to find all objects of type A that have the field "b" that is of type
-B2. We do it like this
+Declarative JDOQL :
 
+[source,java]
 ....
-Declarative JDOQL :
 Query query = pm.newQuery(mydomain.A.class);
 query.setFilter("b instanceof mydomain.B2");
 List results = (List)query.execute();
+....
 
 Single-String JDOQL :
+
+[source,java]
+....
 Query query = pm.newQuery("SELECT FROM mydomain.A WHERE b instanceof mydomain.B2");
 List results = (List)query.execute();
 ....
diff --git a/src/main/asciidoc/jdoql_methods.adoc b/src/main/asciidoc/jdoql_methods.adoc
index e79d050..2f7b457 100644
--- a/src/main/asciidoc/jdoql_methods.adoc
+++ b/src/main/asciidoc/jdoql_methods.adoc
@@ -5,7 +5,8 @@
 
 [[index]]
 
-== JDOQL : Methodsanchor:JDOQL_:_Methods[]
+[[JDOQL_:_Methods]]
+== JDOQL : Methods
 
 When writing the "filter" for a JDOQL Query you can make use of some
 methods on the various Java types. The range of methods included as
@@ -15,7 +16,9 @@ the ones that are available are typically of much use.
 {empty} +
 
 
-=== String Methodsanchor:String_Methods[]
+[[String_Methods]]
+=== String Methods
+
 
 [cols=",",options="header",]
 |===
@@ -100,7 +103,8 @@ List results = (List)query.execute();
 {empty} +
 
 
-=== Collection Methodsanchor:Collection_Methods[]
+[[Collection_Methods]]
+=== Collection Methods
 
 [cols=",",options="header",]
 |===
@@ -138,7 +142,8 @@ List results = (List)query.execute();
 {empty} +
 
 
-=== List Methodsanchor:List_Methods[]
+[[List_Methods]]
+=== List Methods
 
 [cols=",",options="header",]
 |===
@@ -153,7 +158,8 @@ List results = (List)query.execute();
 {empty} +
 
 
-=== Map Methodsanchor:Map_Methods[]
+[[Map_Methods]]
+=== Map Methods
 
 [cols=",",options="header",]
 |===
@@ -198,7 +204,8 @@ List results = (List)query.execute();
 {empty} +
 
 
-=== Temporal Methodsanchor:Temporal_Methods[]
+[[Temporal_Methods]]
+=== Temporal Methods
 
 The following methods apply to fields of temporal types.
 
@@ -285,7 +292,8 @@ The following methods apply to fields of temporal types.
 {empty} +
 
 
-=== Enum Methodsanchor:Enum_Methods[]
+[[Enum_Methods]]
+=== Enum Methods
 
 The following methods apply to fields of type _Enum_
 
@@ -304,7 +312,8 @@ The following methods apply to fields of type _Enum_
 
 {empty} +
 
-=== Optional Methodsanchor:Optional_Methods[]
+[[Optional_Methods]]
+=== Optional Methods
 
 The following methods apply to fields of type _Optional_
 
@@ -327,7 +336,8 @@ The following methods apply to fields of type _Optional_
 {empty} +
 
 
-=== Other Methodsanchor:Other_Methods[]
+[[Other_Methods]]
+=== Other Methods
 
 [cols=",",options="header",]
 |===
diff --git a/src/main/asciidoc/jdoql_result.adoc b/src/main/asciidoc/jdoql_result.adoc
index 672d474..c953fcc 100644
--- a/src/main/asciidoc/jdoql_result.adoc
+++ b/src/main/asciidoc/jdoql_result.adoc
@@ -5,65 +5,58 @@
 
 [[index]]
 
-== JDOQL : Resultanchor:JDOQL_:_Result[]
+[[JDOQL_:_Result]]
+== JDOQL : Result
 
-As we have seen, a JDOQL query is made up of different parts. In this
-section we look at the _result_ part of the query. The result is what we
-want returning. By default (when not specifying the result) the objects
-returned will be of the candidate class type, where they match the query
-filter. Firstly let's look at what you can include in the _result_
-clause.
+As we have seen, a JDOQL query is made up of different parts. 
+In this section we look at the _result_ part of the query. 
+The result is what we want returning. 
+By default (when not specifying the result) the objects returned will be of the candidate class type, where they match the query filter. 
+Firstly let's look at what you can include in the _result_ clause.
 
 * _this_ - the candidate instance
 * A field name
 * A variable
-* A parameter (though why you would want a parameter returning is hard
-to see since you input the value in the first place)
+* A parameter (though why you would want a parameter returning is hard to see since you input the value in the first place)
 * An aggregate (count(), avg(), sum(), min(), max())
 * An expression involving a field (e.g "field1 + 1")
-* A navigational expression (navigating from one field to another ...
-e.g "field1.field4")
+* A navigational expression (navigating from one field to another ... e.g "field1.field4")
 
 The result is specified in JDOQL like this
 
+[source,java]
 ....
 query.setResult("count(field1), field2");
 ....
 
 In *Single-String JDOQL* you would specify it directly.
 
-{empty} +
 
 
-=== Result typeanchor:Result_type[]
+[[Result_type]]
+=== Result type
 
-What you specify in the _result_ defines what form of result you get
-back.
+What you specify in the _result_ of a JDOQL query defines what form of result you get back.
 
-* *Object* - this is returned if you have only a single row in the
-results and a single column. This is achieved when you specified either
-UNIQUE, or just an aggregate (e.g "max(field2)")
-* *Object[]* - this is returned if you have only a single row in the
-results, but more than 1 column (e.g "max(field1), avg(field2)")
-* *List<Object>* - this is returned if you have only a single column in
-the result, and you don't have only aggregates in the result (e.g
-"field2")
-* *List<Object[]>* - this is returned if you have more than 1 column in
-the result, and you don't have only aggregates in the result (e.g
-"field2, avg(field3)")
+* *Object* - this is returned if you have only a single row in the results and a single column. 
+This is achieved when you specified either UNIQUE, or just an aggregate (e.g "max(field2)")
+* *Object[]* - this is returned if you have only a single row in the results, 
+but more than 1 column (e.g "max(field1), avg(field2)")
+* *List<Object>* - this is returned if you have only a single column in the result, 
+and you don't have only aggregates in the result (e.g "field2")
+* *List<Object[]>* - this is returned if you have more than 1 column in the result, 
+and you don't have only aggregates in the result (e.g "field2, avg(field3)")
 
-=== Aggregatesanchor:Aggregates[]
 
-There are situations when you want to return a single number for a
-column, representing an aggregate of the values of all records. There
-are 5 standard JDO2 aggregate functions available. These are
+[[Aggregates]]
+=== Aggregates
 
-* *avg(val)* - returns the average of "val". "val" can be a field,
-numeric field expression or "distinct field".
-* *sum(val)* - returns the sum of "val". "val" can be a field, numeric
-field expression, or "distinct field".
-* *count(val)* - returns the count of records of "val". "val" can be a
-field, or can be "this", or "distinct field".
+There are situations when you want to return a single number for a column, representing an aggregate of the values of all records. 
+There are 5 standard JDOQL aggregate functions available. These are
+
+* *avg(val)* - returns the average of "val". "val" can be a field, numeric field expression or "distinct field".
+* *sum(val)* - returns the sum of "val". "val" can be a field, numeric field expression, or "distinct field".
+* *count(val)* - returns the count of records of "val". "val" can be a field, or can be "this", or "distinct field".
 * *min(val)* - returns the minimum of "val". "val" can be a field
 * *max(val)* - returns the maximum of "val". "val" can be a field
 
@@ -76,33 +69,35 @@ Query q = pm.newQuery("SELECT max(price), min(price) FROM mydomain.Product WHERE
 This will return a single row of results with 2 values, the maximum
 price and the minimum price of all products that have status code of 1.
 
-{empty} +
-
 
-=== Example - Use of aggregatesanchor:Example_-_Use_of_aggregates[]
+[[Example_-_Use_of_aggregates]]
+=== Example - Use of aggregates
 
-JDO 2 introduces the ability to use aggregates in queries. Here's
-another example using the same Product class as above, but this time
-looking for the maximum price of products that are CD Players. Note that
-the result for this particular query will be of type Double since there
+JDOQL has the ability to use aggregates in queries. 
+Here's another example using the same Product class as above, but this time looking for the maximum price of products that are CD Players.
+Note that the result for this particular query will be of type Double since there
 is a single double precision value being returned via the "result".
 
-....
 Declarative JDOQL :
+
+[source,java]
+....
 Query query = pm.newQuery(mydomain.Product.class);
 query.setFilter("name == \"CD Player\"");
 query.setResult("max(this.price)");
 List results = (List)query.execute();
 Iterator iter = c.iterator();
 Double max_price = (Double)iter.next();
+....
 
 Single-String JDOQL :
+
+[source,java]
+....
 Query query = pm.newQuery("SELECT max(price) FROM mydomain.Product WHERE name == \"CD Player\"");
 List results = (List)query.execute();
 Iterator iter = c.iterator();
 Double max_price = (Double)iter.next();
 ....
 
-{empty} +
-
 
diff --git a/src/main/asciidoc/object_retrieval.adoc b/src/main/asciidoc/object_retrieval.adoc
index 675f2c0..a41b1ee 100644
--- a/src/main/asciidoc/object_retrieval.adoc
+++ b/src/main/asciidoc/object_retrieval.adoc
@@ -5,32 +5,45 @@
 
 [[index]]
 
-== Object Retrievalanchor:Object_Retrieval[]
+[[Object_Retrieval]]
+== Object Retrieval
 
-JDO provides persistence of objects. The logical next step after
-persisting objects is to retrieve them for use in your application.
-There are several ways to do this
+Any application will require access to persisted objects.
+The JDO API provides several ways to do this
 
-=== Retrieve an object from its identityanchor:Retrieve_an_object_from_its_identity[]
+
+[[get_object_by_id]]
+=== Retrieve an object from its identity
 
 The simplest form of object retrieval is where we have the identity.
 This is simply
 
+[source,java]
+....
+Person per = (Person)pm.getObjectById(identity);
 ....
-Object obj = pm.getObjectById(identity);
-                
+
+or 
+
+[source,java]
 ....
+Person per = pm.getObjectById(Person.class, identity);
+....
+
+If the object is in the JDO cache (Level 1 or Level 2) then it is retrieved from there,
+otherwise the JDO implementation goes to the datastore. 
+When the object is retrieved its fields are populated according to its Fetch Group.
+
 
-If the object is in the JDO cache then it is retrieved from there,
-otherwise the JDO implementation goes to the datastore. When the object
-is retrieved its fields are populated according to its Fetch Group.
 
-=== Retrieve an object based on its Extentanchor:Retrieve_an_object_based_on_its_Extent[]
+[[extent]]
+=== Retrieve an object based on its Extent
 
-A persistable class can be persisted with an *Extent* of all instances
-of that type. You can use this to retrieve objects of the required type,
-like this
+An *Extent* is a collection of objects of a particular type of object that have been persisted. 
+When you define the MetaData for a class you can define if the class requires an Extent. 
+The default is true. You access the Extent as follows
 
+[source,java]
 ....
 Extent ex = pm.getExtent(MyClass.class, true);
 Iterator iter = ex.iterator();
@@ -41,23 +54,25 @@ while (iter.hasNext())
 }
 ....
 
-The second argument in the _getExtent_ call is whether to include
-instances of subclasses.
+The second argument in the _getExtent_ call is whether to include instances of subclasses.
+An Extent is useful where you want to restrict a Query to query over just that set of objects. 
+It can also be used where you just want to retrieve all persisted objects of a type (as an alternative to using a Query).
 
 {empty} +
 
 
-=== Retrieve an object based on a criteriaanchor:Retrieve_an_object_based_on_a_criteria[]
+[[query]]
+=== Retrieve an object based on a query criteria
 
-Where we want to retrieve all objects based on some criteria (e.g all
-objects of class A where field 'x' of A is a certain value) we need to
-use a query language. JDO2 provides 2 options here. JDOQL is
-object-based and allows you to express your query in terms of the
-classes and fields you are using. SQL is datastore-based and allows you
-to express your query in terms of the datastore tables and columns.
+Where we want to retrieve all objects based on some criteria (e.g all objects of class A where field 'x' of A is a certain value) we need to
+use a query language. 
+The JDO API provides the JDOQL object-based query language where you express your query in terms of classes and fields you are using.
+Dependent on your JDO provider and the datastore being used you may also be able to use a (native) query language such as SQL, expressing
+your query in terms of datastore tables/columns.
 
 To give an example of a JDOQL query
 
+[source,java]
 ....
 Query q = pm.newQuery(MyClass.class, "field1 < value");
 q.declareParameters("int value");
@@ -70,7 +85,6 @@ while (iter.hasNext())
 ....
 
 If the objects found by the query are in the JDO cache then they are
-retrieved from there, otherwise the JDO implementation goes to the
-datastore. When the objects are retrieved their fields are populated
-according to the Fetch Group.
+retrieved from there, otherwise the JDO implementation goes to the datastore. 
+When the objects are retrieved their fields are populated according to the Fetch Group.
 
diff --git a/src/main/asciidoc/pm.adoc b/src/main/asciidoc/pm.adoc
index 5ff84a9..3e31796 100644
--- a/src/main/asciidoc/pm.adoc
+++ b/src/main/asciidoc/pm.adoc
@@ -12,7 +12,7 @@ _PersistenceManager_ (PM). This is obtained from the
 xref:pmf.adoc[PersistenceManagerFactory] for the datastore.
 
 The simplest way of creating a _PersistenceManager_
-link:api20/apidocs/javax/jdo/PersistenceManager.html[image:images/javadoc.png[image]]
+link:api32/apidocs/javax/jdo/PersistenceManager.html[image:images/javadoc.png[image]]
 is as follows
 
 ....
diff --git a/src/main/asciidoc/pmf.adoc b/src/main/asciidoc/pmf.adoc
index 8537a3a..cd66753 100644
--- a/src/main/asciidoc/pmf.adoc
+++ b/src/main/asciidoc/pmf.adoc
@@ -17,7 +17,7 @@ retrieved. The _PersistenceManagerFactory_ can be configured to provide
 particular behaviour.
 
 The simplest way of creating a _PersistenceManagerFactory_
-link:api20/apidocs/javax/jdo/PersistenceManagerFactory.html[image:images/javadoc.png[image]]
+link:api32/apidocs/javax/jdo/PersistenceManagerFactory.html[image:images/javadoc.png[image]]
 is as follows
 
 ....
diff --git a/src/main/asciidoc/query_api.adoc b/src/main/asciidoc/query_api.adoc
new file mode 100644
index 0000000..8d1c950
--- /dev/null
+++ b/src/main/asciidoc/query_api.adoc
@@ -0,0 +1,399 @@
+[[api]]
+= Query API
+:_basedir: 
+:_imagesdir: images/
+:grid: cols
+:query:
+
+
+[[Query_API]]
+== Query API
+
+To understand the JDO Query
+image:../images/javadoc.png[Javadoc, link=api32/apidocs/javax/jdo/Query.html] API we firstly need to look at a typical Query.
+
+Let's create a JDOQL string-based query to highlight its usage
+
+[source,java]
+-----
+Query q = pm.newQuery("SELECT FROM mydomain.Product p WHERE p.price <= :threshold ORDER BY p.price ASC");
+List results = q.execute(my_threshold);
+-----
+
+In this Query, we implicitly select the _JDOQL_ language by just passing in a query string to the method _PersistenceManager.newQuery(String)_, 
+and the query is specified to return all objects of type _Product_ (or subclasses) which have the price less than or equal to some threshold value 
+and ordering the results by the price. 
+We've specified the query like this because we want to pass the threshold value in as a parameter (so maybe running it once with one value, 
+and once with a different value).
+We then set the parameter value of our _threshold_ parameter. 
+The Query is then executed to return a List of results. 
+The example is to highlight the typical methods specified for a (JDOQL) string-based Query.
+
+
+
+
+=== Creating a query
+
+The principal ways of creating a query are
+
+
+* Specifying the query language, and using a single-string form of the query
+[source,java]
+-----
+Query q = pm.newQuery("javax.jdo.query.JDOQL", 
+    "SELECT FROM mydomain.MyClass WHERE field2 < threshold PARAMETERS java.util.Date threshold");
+-----
+or alternatively
+[source,java]
+-----
+Query q = pm.newQuery("SQL", "SELECT * FROM MYTABLE WHERE COL1 == 25);
+-----
+* A link:#named["named" query], (pre-)defined in metadata (refer to metadata docs).
+[source,java]
+-----
+Query<MyClass> q = pm.newNamedQuery(MyClass.class, "MyQuery1");
+-----
+* JDOQL : Use the link:jdoql.html#singlestring[single-string] form of the query
+[source,java]
+-----
+Query q = pm.newQuery("SELECT FROM mydomain.MyClass WHERE field2 < threshold PARAMETERS java.util.Date threshold");
+-----
+* JDOQL : Use the link:jdoql.html#jdoql[declarative API] to define the query
+[source,java]
+-----
+Query<MyClass> q = pm.newQuery(MyClass.class);
+q.setFilter("field2 < threshold");
+q.declareParameters("java.util.Date threshold");
+-----
+* JDOQL : Use the link:jdoql.html#jdoql_typed[Typed Query API] to define the query
+[source,java]
+-----
+JDOQLTypedQuery<MyClass> q = pm.newJDOQLTypedQuery(MyClass.class);
+QMyClass cand = QMyClass.candidate();
+List<Product> results = q.filter(cand.field2.lt(q.doubleParameter("threshold"))).executeList();
+-----
+
+
+=== Closing a query
+
+When a query is executed it will have access to the results of that query.
+Each time it is executed (maybe with different parameters) it will have separate results.
+This can consume significant resources if the query returned a lot of records.
+
+You close a query (and all query results) like this
+
+[source,java]
+-----
+q.close();
+-----
+
+If you just wanted to close a specific query result you would call
+
+[source,java]
+-----
+q.close(queryResult);
+-----
+where the _queryResult_ is what you were returned from executing the query.
+
+
+
+[[named]]
+=== Named Query
+
+With the JDO Query API you can either define a query at runtime, or define it in the MetaData/annotations for a class and refer to it at runtime using a symbolic name. 
+This second option means that the method of invoking the query at runtime is much simplified. 
+To demonstrate the process, lets say we have a class called _Product_ (something to sell in a store). 
+We define the JDO Meta-Data for the class in the normal way, but we also have some query that we know we will require, so we define the following in the Meta-Data.
+
+[source,xml]
+-----
+<package name="mydomain">
+    <class name="Product">
+        ...
+        <query name="SoldOut" language="javax.jdo.query.JDOQL"><![CDATA[
+        SELECT FROM mydomain.Product WHERE status == "Sold Out"
+        ]]></query>
+    </class>
+</package>
+-----
+
+So we have a JDOQL query called "SoldOut" defined for the class _Product_ that returns all Products (and subclasses) that have a _status_ of "Sold Out". 
+Out of interest, what we would then do in our application to execute this query woule be
+
+[source,java]
+-----
+Query<Product> q = pm.newNamedQuery(mydomain.Product.class,"SoldOut");
+List<Product> results = q.executeList();
+-----
+
+The above example was for the JDOQL object-based query language. We can do a similar thing using SQL, so we define the following in our MetaData for our _Product_ class
+
+[source,xml]
+-----
+<jdo>
+    <package name="mydomain">
+        <class name="Product">
+            ...
+            <query name="PriceBelowValue" language="javax.jdo.query.SQL"><![CDATA[
+            SELECT NAME FROM PRODUCT WHERE PRICE < ?
+            ]]></query>
+        </class>
+    </package>
+</jdo>
+-----
+
+So here we have an SQL query that will return the names of all Products that have a price less than a specified value. 
+This leaves us the flexibility to specify the value at runtime. So here we run our named query, asking for the names of all Products with price below 20 euros.
+
+[source,java]
+-----
+Query<Product> q = pm.newNamedQuery(mydomain.Product.class, "PriceBelowValue");
+q.setParameters(20.0);
+List<Product> results = q.executeList();
+-----
+
+All of the examples above have been specifed within the <class> element of the MetaData. 
+You can, however, specify queries below <jdo> in which case the query is not scoped by a particular candidate class. 
+In this case you must put your queries in any of the following MetaData files
+
+-----
+/META-INF/package.jdo
+/WEB-INF/package.jdo
+/package.jdo
+/META-INF/package-{mapping}.orm
+/WEB-INF/package-{mapping}.orm
+/package-{mapping}.orm
+/META-INF/package.jdoquery
+/WEB-INF/package.jdoquery
+/package.jdoquery
+-----
+
+
+
+[[save_as_named]]
+==== Saving a Query as a Named Query
+
+JDO also allows you to create a query, and then save it as a "named" query for later reuse. You do this as follows
+
+[source,java]
+-----
+Query q = pm.newQuery("SELECT FROM mydomain.Product p WHERE ...");
+q.saveAsNamedQuery("MyQuery");
+-----
+
+and you can thereafter access the query via
+
+[source,java]
+-----
+Query q = pm.newNamedQuery(Product.class, "MyQuery");
+-----
+
+
+
+[[query_extensions]]
+=== Query Extensions
+
+The JDO query API allows implementations to support "extensions" and provides a simple interface for enabling the use of such extensions on queries.
+An extension specifies additional information to the query mechanism about how to perform the query. 
+Individual extensions will be explained later in this guide.
+
+You set an extension like this
+
+[source,java]
+-----
+q.extension("extension_name", value);
+-----
+
+[source,java]
+-----
+Map exts = new HashMap();
+exts.put("extension1", value1);
+exts.put("extension2", value2);
+q.extensions(exts);
+-----
+
+The Query API also has methods _setExtensions_ and _addExtension_ that are from the original version of the API, but function the same as these methods quoted.
+
+NOTE: Refer to the documentation of your JDO provider for what extensions are supported.
+
+
+[[query_parameters]]
+=== Setting query parameters
+
+Queries can be made flexible and reusable by defining parameters as part of the query, so that we can execute the same query
+with different sets of parameters and minimise resources.
+
+[source,java]
+-----
+// JDOQL Using named parameters
+Query<Product> q = pm.newQuery(Product.class);
+q.setFilter("this.name == :name && this.serialNo == :serial");
+
+Map params = new HashMap();
+params.put("name", "Walkman");
+params.put("serial", "123021");
+q.setNamedParameters(params);
+
+
+// JDOQL Using numbered parameters
+Query<Product> q = pm.newQuery(Product.class);
+q.setFilter("this.name == ?1 && this.serialNo == ?2");
+
+q.setParameters("Walkman", "123021");
+-----
+
+Alternatively you can specify the query parameters in the _execute_ method call.
+
+
+[[compile]]
+=== Compiling a query
+
+An intermediate step once you have your query defined, if you want to check its validity, is to _compile_ it. You do this as follows
+
+[source,java]
+-----
+q.compile();
+-----
+
+If the query is invalid, then a JDOException will be thrown.
+
+
+
+=== Executing a query
+
+So we have set up our query. We now execute it. We have various methods to do this, depending on what result we are expecting etc
+
+[source,java]
+-----
+// Simple execute
+Object result = q.execute();
+
+// Execute with 1 parameter passed in
+Object result = q.execute(paramVal1);
+
+// Execute with multiple parameters passed in 
+Object result = q.execute(paramVal1, paramVal2);
+
+// Execute with an array of parameters passed in (positions match the query parameter position)
+Object result = q.executeWithArray(new Object[]{paramVal1, paramVal2});
+
+// Execute with a map of parameters keyed by their name in the query
+Object result = q.executeWithMap(paramMap);
+
+// Execute knowing we want to receive a list of results
+List results = q.executeList();
+
+// Execute knowing there is 1 result row
+Object result = q.executeUnique();
+
+// Execute where we want a list of results and want each result row of a particular type
+List<ResultClass> results = q.executeResultList(ResultClass.class);
+
+// Execute where we want a single result and want the result row of a particular type
+ResultClass result = q.executeResultUnique(ResultClass.class);
+-----
+
+[[resultclass]]
+=== Result Class
+
+By default a JDO query of whatever language will return a result matching the result clause. You can override this if you wish by specifying a result class. 
+If your query has only a single row in the results then you will get an object of your result class back, otherwise you get a List of result class objects.
+The _Result Class_ has to meet certain requirements. These are
+
+* Can be one of Integer, Long, Short, Float, Double, Character, Byte, Boolean, String, java.math.BigInteger, java.math.BigDecimal, 
+java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp, java.time.LocalDate, java.time.LocalTime, java.time.LocalDateTime, or Object[]
+* Can be a user-defined class, that has either a constructor taking arguments of the same type as those returned by the query (in the same order), 
+or has a public put(Object, Object) method, or public setXXX() methods, or public fields.
+
+Please look at the specific help for the query language you are using for details of a user-defined result class.
+
+
+
+
+[[FetchPlan]]
+=== Controlling the execution : FetchPlan
+
+When a Query is executed it executes in the datastore, which returns a set of results. 
+Your JDO provider could clearly read all results from this ResultSet in one go and return them all to the user, or could allow control over this fetching process. 
+JDO provides a _fetch size_ on the _Fetch Plan_ to allow this control. You would set this as follows
+
+[source,java]
+-----
+Query q = pm.newQuery(...);
+q.getFetchPlan().setFetchSize(FetchPlan.FETCH_SIZE_OPTIMAL);
+-----
+
+_fetch size_ has 3 possible values. 
+
+* *FETCH_SIZE_OPTIMAL* - allows your JDO provider full control over the fetching. 
+In this case your JDO provider will fetch each object when they are requested, and then when the owning transaction is committed will retrieve all remaining rows 
+(so that the Query is still usable after the close of the transaction).
+* *FETCH_SIZE_GREEDY* - Your JDO provider will read all objects in at query execution.
+This can be efficient for queries with few results, and very inefficient for queries returning large result sets.
+* *A positive value* - Your JDO provider will read this number of objects at query execution. Thereafter it will read the objects when requested.
+
+
+In addition to the number of objects fetched, you can also control which fields are fetched for each object of the candidate type. This is controlled via the _FetchPlan_.
+
+
+
+[[ignore_cache]]
+=== ignoreCache(), setIgnoreCache()
+
+The ignoreCache option setting specifies whether when processing the query results it should check for the retrieved objects in the cache.
+
+[source,java]
+-----
+q.ignoreCache(true);
+-----
+
+
+
+[[locking]]
+=== Control over locking of fetched objects
+
+JDO allows control over whether objects found by a query are locked during that transaction so that other transactions can't update them in the meantime. 
+To do this you would do
+
+[source,java]
+-----
+Query q = pm.newQuery(...);
+q.serializeRead(true);
+-----
+
+In addition you can perform this on a per-transaction basis by doing
+
+[source,java]
+-----
+tx.setSerializeRead(true);
+-----
+
+NOTE: If the datastore in use doesn't support locking of objects then this will do nothing
+
+
+
+[[read_timeout]]
+=== Timeout on query execution for reads
+
+[source,java]
+-----
+q.datastoreReadTimeoutMillis(1000);
+-----
+
+_Sets the timeout for this query (in milliseconds)._ 
+Will throw a JDOUnsupportedOperationException if the query implementation doesn't support timeouts (for the current datastore).
+
+
+
+[[write_timeout]]
+=== Timeout on query execution for writes
+
+[source,java]
+-----
+q.datastoreWriteTimeoutMillis(1000);
+-----
+
+_Sets the timeout for this query (in milliseconds) when it is a delete/update._ 
+Will throw a JDOUnsupportedOperationException if the query implementation doesn't support timeouts (for the current datastore).
+
+
diff --git a/src/main/template/document.html.erb b/src/main/template/document.html.erb
index 3bd41cc..51a8f28 100644
--- a/src/main/template/document.html.erb
+++ b/src/main/template/document.html.erb
@@ -200,12 +200,12 @@
                     <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Query<span class="caret"></span></a>
                   <% end %>
                     <ul class="dropdown-menu">
+                        <li><a href="<%= (attr :_basedir) %>query_api.html">Query API</a></li>
+                        <li role="separator" class="divider"></li>
                         <li><a href="<%= (attr :_basedir) %>jdoql.html">JDOQL</a></li>
-                        <li><a href="<%= (attr :_basedir) %>jdoql_result.html">Result</a></li>
                         <li><a href="<%= (attr :_basedir) %>jdoql_methods.html">Methods</a></li>
+                        <li><a href="<%= (attr :_basedir) %>jdoql_result.html">Result</a></li>
                         <li><a href="<%= (attr :_basedir) %>jdoql_quickref.pdf">Quick Ref PDF</a></li>
-                        <li role="separator" class="divider"></li>
-                        <li><a href="<%= (attr :_basedir) %>extents.html">Extents</a></li>
                     </ul>
                </li>