[#3712] Add Oracle Spatial examples

This commit is contained in:
lukaseder 2014-12-22 14:48:39 +01:00
parent 1abf3ec3ba
commit b2189425e1
8 changed files with 507 additions and 5 deletions

View File

@ -5,7 +5,7 @@ Please visit http://www.jooq.org for more information.
Because this example is making use of the Oracle SQL dialect, it does not run with the jOOQ Open Source Edition, which does not support Oracle. In order to run this example, please get a commercial or trial distribution directly from: http://www.jooq.org/download.
Before you run this example, you will need to create the following user:
Before you run this example, you will need to create the following user in your Oracle database:
```sql
C:\> sqlplus "/ as sysdba"
@ -29,6 +29,8 @@ SQL> GRANT EXECUTE ON DBMS_AQADM TO SP;
```
If you do not have the rights to create users, you can also change the user in `config.properties` and in `db-oracle.sql`.
To install and run this example, please use Maven and Java 8 to install the latest distribution of jOOQ Professional Edition:
```
@ -40,5 +42,7 @@ $ mvn clean install
...
$ cd jOOQ-examples/jOOQ-oracle-example
...
$ cp /path/to/ojdbc6.jar lib
...
$ mvn clean install
```

View File

@ -0,0 +1 @@
/ojdbc6.jar

View File

@ -34,6 +34,8 @@
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${db.oracle.version}</version>
<scope>system</scope>
<systemPath>${basedir}/lib/ojdbc6.jar</systemPath>
</dependency>
<!-- Logging -->
@ -137,6 +139,8 @@
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${db.oracle.version}</version>
<scope>system</scope>
<systemPath>${basedir}/lib/ojdbc6.jar</systemPath>
</dependency>
</dependencies>
</plugin>
@ -165,10 +169,25 @@
<name>org.jooq.util.DefaultGenerator</name>
<database>
<name>org.jooq.util.oracle.OracleDatabase</name>
<includes>.*</includes>
<excludes></excludes>
<includes>
# Generate the complete SP user
SP\..*
# Generate only parts of the geospatial API
| MDSYS\.SDO_GEOM.*?
</includes>
<!-- Known issue with this type: https://github.com/jOOQ/jOOQ/issues/3709 -->
<excludes>ST_ANNOTATIONTEXTELEMENT</excludes>
<dateAsTimestamp>true</dateAsTimestamp>
<inputSchema>SP</inputSchema>
<schemata>
<schema>
<inputSchema>SP</inputSchema>
</schema>
<schema>
<inputSchema>MDSYS</inputSchema>
</schema>
</schemata>
</database>
<generate>
<deprecated>false</deprecated>
@ -181,6 +200,16 @@
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${db.oracle.version}</version>
<scope>system</scope>
<systemPath>${basedir}/lib/ojdbc6.jar</systemPath>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

View File

@ -204,3 +204,109 @@ BEGIN
COMMIT;
END;
/
BEGIN
-- Examples can be found here:
-- https://docs.oracle.com/cd/B19306_01/appdev.102/b14255/sdo_objrelschema.htm#SPATL020
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE cola_markets';
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE (SQLERRM);
END;
END;
/
CREATE TABLE cola_markets (
mkt_id NUMBER PRIMARY KEY,
name VARCHAR2(32),
shape SDO_GEOMETRY)
/
INSERT INTO cola_markets VALUES(
1,
'cola_a',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,3), -- one rectangle (1003 = exterior)
SDO_ORDINATE_ARRAY(1,1, 5,7) -- only 2 points needed to
-- define rectangle (lower left and upper right) with
-- Cartesian-coordinate data
)
)
/
INSERT INTO cola_markets VALUES(
2,
'cola_b',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,1), -- one polygon (exterior polygon ring)
SDO_ORDINATE_ARRAY(5,1, 8,1, 8,6, 5,7, 5,1)
)
)
/
INSERT INTO cola_markets VALUES(
3,
'cola_c',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,1), -- one polygon (exterior polygon ring)
SDO_ORDINATE_ARRAY(3,3, 6,3, 6,5, 4,5, 3,3)
)
)
/
INSERT INTO cola_markets VALUES(
4,
'cola_d',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,4), -- one circle
SDO_ORDINATE_ARRAY(8,7, 10,9, 8,11)
)
)
/
BEGIN
INSERT INTO user_sdo_geom_metadata
(TABLE_NAME,
COLUMN_NAME,
DIMINFO,
SRID)
VALUES (
'cola_markets',
'shape',
SDO_DIM_ARRAY( -- 20X20 grid
SDO_DIM_ELEMENT('X', 0, 20, 0.005),
SDO_DIM_ELEMENT('Y', 0, 20, 0.005)
),
NULL -- SRID
);
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE (SQLERRM);
END;
/
CREATE INDEX cola_spatial_idx
ON cola_markets(shape)
INDEXTYPE IS MDSYS.SPATIAL_INDEX
/

View File

@ -0,0 +1,136 @@
/**
* Copyright (c) 2009-2013, Data Geekery GmbH (http://www.datageekery.com)
* All rights reserved.
*
* This work is dual-licensed
* - under the Apache Software License 2.0 (the "ASL")
* - under the jOOQ License and Maintenance Agreement (the "jOOQ License")
* =============================================================================
* You may choose which license applies to you:
*
* - If you're using this work with Open Source databases, you may choose
* either ASL or jOOQ License.
* - If you're using this work with at least one commercial database, you must
* choose jOOQ License
*
* For more information, please visit http://www.jooq.org/licenses
*
* Apache Software License 2.0:
* -----------------------------------------------------------------------------
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* jOOQ License and Maintenance Agreement:
* -----------------------------------------------------------------------------
* Data Geekery grants the Customer the non-exclusive, timely limited and
* non-transferable license to install and use the Software under the terms of
* the jOOQ License and Maintenance Agreement.
*
* This library is distributed with a LIMITED WARRANTY. See the jOOQ License
* and Maintenance Agreement for more details: http://www.jooq.org/licensing
*/
package org.jooq.example;
import static java.util.stream.Collectors.toList;
import static java.util.stream.IntStream.range;
import static org.jooq.example.db.oracle.sp.Queues.NEW_AUTHOR_AQ;
// ...
// ...
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.jooq.example.db.oracle.sp.udt.records.AuthorTRecord;
import org.jooq.exception.DataAccessException;
import org.jooq.impl.DSL;
// ...
// ...
// ...
// ...
import org.junit.Test;
/**
* @author Lukas Eder
*/
public class OracleAQExamples extends Utils {
// Generate 10 authors
static final List<AuthorTRecord> authors =
range(0, 10).mapToObj(i -> new AuthorTRecord(i, "F" + i, "L1" + i, null)).collect(toList());
@Test
public void testAQSimple() throws Exception {
dsl.transaction(c -> {
// Enqueue all authors
authors.stream().forEach(a -> {
DBMS_AQ.enqueue(dsl.configuration(), NEW_AUTHOR_AQ, a);
});
// Dequeue them again
authors.stream().forEach(a -> {
assertEquals(a, DBMS_AQ.dequeue(dsl.configuration(), NEW_AUTHOR_AQ));
});
});
}
@Test
public void testAQOptions() throws Exception {
dsl.transaction(c -> {
MESSAGE_PROPERTIES_T props = new MESSAGE_PROPERTIES_T();
ENQUEUE_OPTIONS_T enq = new ENQUEUE_OPTIONS_T().visibility(IMMEDIATE);
// Enqueue two authors
DBMS_AQ.enqueue(c, NEW_AUTHOR_AQ, authors.get(0), enq, props);
DBMS_AQ.enqueue(c, NEW_AUTHOR_AQ, authors.get(1), enq, props);
// Dequeue them again
DEQUEUE_OPTIONS_T deq = new DEQUEUE_OPTIONS_T().wait(NO_WAIT);
assertEquals(authors.get(0), DBMS_AQ.dequeue(c, NEW_AUTHOR_AQ, deq, props));
assertEquals(authors.get(1), DBMS_AQ.dequeue(c, NEW_AUTHOR_AQ, deq, props));
// The queue is empty, this should fail
assertThrows(DataAccessException.class, () -> {
DBMS_AQ.dequeue(c, NEW_AUTHOR_AQ, deq, props);
});
});
}
@Test
public void testAQTransactions() throws Exception {
dsl.transaction(c1 -> {
// Enqueue an author
DBMS_AQ.enqueue(c1, NEW_AUTHOR_AQ, authors.get(0));
// This nested transaction is rolled back to its savepoint
assertThrows(RuntimeException.class, () -> {
DSL.using(c1).transaction(c2 -> {
DBMS_AQ.enqueue(c2, NEW_AUTHOR_AQ, authors.get(1));
throw new RuntimeException();
});
});
// Dequeue the first author
MESSAGE_PROPERTIES_T props = new MESSAGE_PROPERTIES_T();
DEQUEUE_OPTIONS_T deq = new DEQUEUE_OPTIONS_T().wait(NO_WAIT);
assertEquals(authors.get(0), DBMS_AQ.dequeue(c1, NEW_AUTHOR_AQ, deq, props));
// The queue is empty (due to the rollback), this should fail
assertThrows(DataAccessException.class, () -> {
DBMS_AQ.dequeue(c1, NEW_AUTHOR_AQ, deq, props);
});
});
}
}

View File

@ -0,0 +1,95 @@
/**
* Copyright (c) 2009-2013, Data Geekery GmbH (http://www.datageekery.com)
* All rights reserved.
*
* This work is dual-licensed
* - under the Apache Software License 2.0 (the "ASL")
* - under the jOOQ License and Maintenance Agreement (the "jOOQ License")
* =============================================================================
* You may choose which license applies to you:
*
* - If you're using this work with Open Source databases, you may choose
* either ASL or jOOQ License.
* - If you're using this work with at least one commercial database, you must
* choose jOOQ License
*
* For more information, please visit http://www.jooq.org/licenses
*
* Apache Software License 2.0:
* -----------------------------------------------------------------------------
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* jOOQ License and Maintenance Agreement:
* -----------------------------------------------------------------------------
* Data Geekery grants the Customer the non-exclusive, timely limited and
* non-transferable license to install and use the Software under the terms of
* the jOOQ License and Maintenance Agreement.
*
* This library is distributed with a LIMITED WARRANTY. See the jOOQ License
* and Maintenance Agreement for more details: http://www.jooq.org/licensing
*/
package org.jooq.example;
import static org.jooq.example.db.oracle.sp.Tables.AUTHORS;
import static org.jooq.example.db.oracle.sp.Tables.BOOKS;
import static org.jooq.impl.DSL.using;
import org.jooq.example.db.oracle.sp.packages.Library;
import org.junit.Before;
import org.junit.Test;
/**
* @author Lukas Eder
*/
public class OracleProcedureExamples extends Utils {
@Before
public void setup() {
dsl.transaction(ctx -> {
using(ctx).delete(BOOKS).execute();
using(ctx).delete(AUTHORS).execute();
using(ctx).insertInto(AUTHORS, AUTHORS.ID, AUTHORS.FIRST_NAME, AUTHORS.LAST_NAME)
.values(1, "George", "Orwell")
.values(2, "Paulo" , "Coelho")
.execute();
using(ctx).insertInto(BOOKS, BOOKS.ID, BOOKS.TITLE, BOOKS.LANGUAGE, BOOKS.AUTHOR_ID)
.values(1, "1984" , "en", 1)
.values(2, "Animal Farm" , "en", 1)
.values(3, "O Alquimista", "pt", 2)
.values(4, "Brida" , "en", 2)
.execute();
});
}
@Test
public void testProcedures() {
// TODO: Work on this nice table unnesting syntax, which currently doesn't work.
// dsl.selectFrom(table(Library.getAuthors(null, 1)))
// .fetch();
dsl.select(AUTHORS.FIRST_NAME, AUTHORS.LAST_NAME, Library.getBooks(AUTHORS.ID))
.from(AUTHORS)
.fetch()
.forEach(author -> {
System.out.println();
System.out.println("Author " + author.getValue(AUTHORS.FIRST_NAME) + " " + author.getValue(AUTHORS.LAST_NAME) + " wrote: ");
author.value3().getList().forEach(book -> {
System.out.println(book.getTitle());
});
});
}
}

View File

@ -0,0 +1,131 @@
/**
* Copyright (c) 2009-2013, Data Geekery GmbH (http://www.datageekery.com)
* All rights reserved.
*
* This work is dual-licensed
* - under the Apache Software License 2.0 (the "ASL")
* - under the jOOQ License and Maintenance Agreement (the "jOOQ License")
* =============================================================================
* You may choose which license applies to you:
*
* - If you're using this work with Open Source databases, you may choose
* either ASL or jOOQ License.
* - If you're using this work with at least one commercial database, you must
* choose jOOQ License
*
* For more information, please visit http://www.jooq.org/licenses
*
* Apache Software License 2.0:
* -----------------------------------------------------------------------------
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* jOOQ License and Maintenance Agreement:
* -----------------------------------------------------------------------------
* Data Geekery grants the Customer the non-exclusive, timely limited and
* non-transferable license to install and use the Software under the terms of
* the jOOQ License and Maintenance Agreement.
*
* This library is distributed with a LIMITED WARRANTY. See the jOOQ License
* and Maintenance Agreement for more details: http://www.jooq.org/licensing
*/
package org.jooq.example;
import static org.jooq.example.db.oracle.sp.Tables.COLA_MARKETS;
import static org.jooq.impl.DSL.val;
import org.jooq.Record1;
import org.jooq.example.db.oracle.mdsys.packages.SdoGeom;
import org.jooq.example.db.oracle.sp.tables.ColaMarkets;
import org.junit.Test;
/**
* @author Lukas Eder
*/
public class OracleSpatialExamples extends Utils {
@Test
public void testSDO_GEOM() {
// These examples were inspired from the examples given in the Oracle
// documentation:
// https://docs.oracle.com/cd/B19306_01/appdev.102/b14255/sdo_objrelschema.htm#SPATL020
// OTN License restrictions may apply.
ColaMarkets c_a = COLA_MARKETS.as("c_a");
ColaMarkets c_b = COLA_MARKETS.as("c_b");
ColaMarkets c_c = COLA_MARKETS.as("c_c");
ColaMarkets c_d = COLA_MARKETS.as("c_d");
// SELECT SDO_GEOM.SDO_INTERSECTION(c_a.shape, c_c.shape, 0.005)
// FROM cola_markets c_a, cola_markets c_c
// WHERE c_a.name = 'cola_a' AND c_c.name = 'cola_c';
System.out.println();
System.out.println("Return the topological intersection of two geometries.");
System.out.println("------------------------------------------------------");
dsl.select(SdoGeom.sdoIntersection2(c_a.SHAPE, c_c.SHAPE, val(0.005)))
.from(c_a, c_c)
.where(c_a.NAME.eq("cola_a"))
.and(c_c.NAME.eq("cola_c"))
.fetch()
.map(Record1::value1)
.forEach(System.out::println);
// SELECT SDO_GEOM.RELATE(c_b.shape, 'anyinteract', c_d.shape, 0.005)
// FROM cola_markets c_b, cola_markets c_d
// WHERE c_b.name = 'cola_b' AND c_d.name = 'cola_d';
System.out.println();
System.out.println("Do two geometries have any spatial relationship?");
System.out.println("------------------------------------------------");
dsl.select(SdoGeom.relate6(c_b.SHAPE, val("anyinteract"), c_d.SHAPE, val(0.005)))
.from(c_b, c_d)
.where(c_b.NAME.eq("cola_b"))
.and(c_d.NAME.eq("cola_d"))
.fetch()
.map(Record1::value1)
.forEach(System.out::println);
// -- Return the areas of all cola markets.
// SELECT name, SDO_GEOM.SDO_AREA(shape, 0.005) FROM cola_markets;
System.out.println();
System.out.println("Return the areas of all cola markets.");
System.out.println("-------------------------------------");
dsl.select(SdoGeom.sdoArea2(c_a.SHAPE, val(0.005)))
.from(c_a)
.fetch()
.map(Record1::value1)
.forEach(System.out::println);
// SELECT SDO_GEOM.SDO_DISTANCE(c_b.shape, c_d.shape, 0.005)
// FROM cola_markets c_b, cola_markets c_d
// WHERE c_b.name = 'cola_b' AND c_d.name = 'cola_d';
System.out.println();
System.out.println("Return the distance between two geometries.");
System.out.println("-------------------------------------------");
dsl.select(SdoGeom.sdoDistance2(c_b.SHAPE, c_d.SHAPE, val(0.005)))
.from(c_b, c_d)
.where(c_b.NAME.eq("cola_b"))
.and(c_d.NAME.eq("cola_d"))
.fetch()
.map(Record1::value1)
.forEach(System.out::println);
}
}

View File

@ -64,7 +64,7 @@ public class Utils {
@BeforeClass
public static void start() throws Exception {
Properties p = new Properties();
p.load(QueriesWithTypes.class.getResourceAsStream("/config.properties"));
p.load(OracleAQExamples.class.getResourceAsStream("/config.properties"));
connection = getConnection(p.getProperty("db.url"), p.getProperty("db.username"), p.getProperty("db.password"));
dsl = using(connection);