Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Oracle Collections implementation #1425

Draft
wants to merge 2 commits into
base: 4.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ static Future<OracleConnection> connect(Vertx vertx, String connectionUri) {
return connect(vertx, fromUri(connectionUri));
}

Object createArray(String typeName, Object elements);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add some Javadoc to this method?


/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.vertx.sqlclient.impl.SingletonSupplier;
import io.vertx.sqlclient.impl.SqlConnectionBase;
import io.vertx.sqlclient.spi.ConnectionFactory;
import oracle.jdbc.internal.OracleArray;

public class OracleConnectionImpl extends SqlConnectionBase<OracleConnectionImpl> implements OracleConnection {

Expand All @@ -33,4 +34,9 @@ public static Future<OracleConnection> connect(Vertx vertx, OracleConnectOptions
OracleConnectionFactory client = new OracleConnectionFactory(ctx.owner(), SingletonSupplier.wrap(options));
return prepareForClose(ctx, client.connect(ctx)).map(OracleConnection::cast);
}

@Override
public Object createArray(String typeName, Object elements) {
return ((OracleJdbcConnection) conn.unwrap()).createArray(typeName, elements);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ public OracleJdbcConnection(ContextInternal ctx, ClientMetrics metrics, OracleCo
this.metadata = metadata;
}

public Object createArray(String typeName, Object elements) {
try {
return connection.createARRAY( typeName, elements );
}
catch (SQLException e) {
throw new RuntimeException( e );
}
}

@Override
public int pipeliningLimit() {
return 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.vertx.oracleclient.test;

import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;

import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import io.vertx.oracleclient.OracleBuilder;
import io.vertx.oracleclient.OracleConnection;
import io.vertx.oracleclient.test.junit.OracleRule;
import io.vertx.sqlclient.Pool;
import io.vertx.sqlclient.Tuple;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;

@RunWith(VertxUnitRunner.class)
public class OracleArrayTest extends OracleTestBase {

@ClassRule
public static OracleRule oracle = OracleRule.SHARED_INSTANCE;

Pool pool;

@Before
public void setUp() throws Exception {
pool = OracleBuilder.pool( builder -> builder
.connectingTo(oracle.options())
.using(vertx));
}

@Test
public void testStringArray(TestContext ctx) {
String[] elements = {"str1", "str2", "str3"};
pool.withConnection(conn -> {
Object stringsArray = ((OracleConnection)conn).createArray( "StringArrayType", elements );
String insertSql = "INSERT INTO StringsArrayTable( id, stringsArray) VALUES (?, ?)";
return conn.preparedQuery( insertSql ).execute( Tuple.of(1, stringsArray) );
}).onComplete( ctx.asyncAssertSuccess() );
}

@After
public void tearDown(TestContext ctx) throws Exception {
pool.close(ctx.asyncAssertSuccess());
}
}
31 changes: 31 additions & 0 deletions vertx-oracle-client/src/test/resources/tck/import.sql
Original file line number Diff line number Diff line change
Expand Up @@ -170,5 +170,36 @@ CREATE TABLE passenger
address_id NUMBER
);


-- These are the sql commands executed by ORM to facilitate support for String[] array type
CREATE OR REPLACE TYPE StringArrayType AS VARYING array(127) of varchar2(255 char);

CREATE TABLE StringsArrayTable
(
id number(10,0),
stringarrayelement StringArrayType,
primary key (id)
);

-- The following is ORM-generated DDL to manage various array use situations in embedded and type conversion situations and may or may not be relevant at the moment
--create or replace function StringArrayType_cmp(a in StringArrayType, b in StringArrayType) return number deterministic is begin if a is null or b is null then return null; end if; for i in 1 .. least(a.count,b.count) loop if a(i) is null or b(i) is null then return null;elsif a(i)>b(i) then return 1;elsif a(i)<b(i) then return -1; end if; end loop; if a.count=b.count then return 0; elsif a.count>b.count then return 1; else return -1; end if; end;
--create or replace function StringArrayType_distinct(a in StringArrayType, b in StringArrayType) return number deterministic is begin if a is null and b is null then return 0; end if; if a is null or b is null or a.count <> b.count then return 1; end if; for i in 1 .. a.count loop if (a(i) is null)<>(b(i) is null) or a(i)<>b(i) then return 1; end if; end loop; return 0; end;
--create or replace function StringArrayType_position(arr in StringArrayType, elem in varchar2, startPos in number default 1) return number deterministic is begin if arr is null then return null; end if; if elem is null then for i in startPos .. arr.count loop if arr(i) is null then return i; end if; end loop; else for i in startPos .. arr.count loop if arr(i)=elem then return i; end if; end loop; end if; return 0; end;
--create or replace function StringArrayType_length(arr in StringArrayType) return number deterministic is begin if arr is null then return null; end if; return arr.count; end;
--create or replace function StringArrayType_concat(arr0 in StringArrayType,arr1 in StringArrayType,arr2 in StringArrayType default StringArrayType(),arr3 in StringArrayType default StringArrayType(),arr4 in StringArrayType default StringArrayType()) return StringArrayType deterministic is res StringArrayType; begin if arr0 is null or arr1 is null or arr2 is null or arr3 is null or arr4 is null then return null; end if; select * bulk collect into res from (select * from table(arr0) union all select * from table(arr1) union all select * from table(arr2) union all select * from table(arr3) union all select * from table(arr4)); return res; end;
--create or replace function StringArrayType_contains(haystack in StringArrayType, needle in StringArrayType, nullable in number) return number deterministic is found number(1,0); begin if haystack is null or needle is null then return null; end if; for i in 1 .. needle.count loop found := 0; for j in 1 .. haystack.count loop if nullable = 1 and needle(i) is null and haystack(j) is null or needle(i)=haystack(j) then found := 1; exit; end if; end loop; if found = 0 then return 0; end if;end loop; return 1; end;
--create or replace function StringArrayType_overlaps(haystack in StringArrayType, needle in StringArrayType, nullable in number) return number deterministic is begin if haystack is null or needle is null then return null; end if; if needle.count = 0 then return 1; end if; for i in 1 .. needle.count loop for j in 1 .. haystack.count loop if nullable = 1 and needle(i) is null and haystack(j) is null or needle(i)=haystack(j) then return 1; end if; end loop; end loop; return 0; end;
--create or replace function StringArrayType_get(arr in StringArrayType, idx in number) return varchar2 deterministic is begin if arr is null or idx is null or arr.count < idx then return null; end if; return arr(idx); end;
--create or replace function StringArrayType_set(arr in StringArrayType, idx in number, elem in varchar2) return StringArrayType deterministic is res StringArrayType:=StringArrayType(); begin if arr is not null then for i in 1 .. arr.count loop res.extend; res(i) := arr(i); end loop; for i in arr.count+1 .. idx loop res.extend; end loop; else for i in 1 .. idx loop res.extend; end loop; end if; res(idx) := elem; return res; end;
--create or replace function StringArrayType_remove(arr in StringArrayType, elem in varchar2) return StringArrayType deterministic is res StringArrayType:=StringArrayType(); begin if arr is null then return null; end if; if elem is null then for i in 1 .. arr.count loop if arr(i) is not null then res.extend; res(res.last) := arr(i); end if; end loop; else for i in 1 .. arr.count loop if arr(i) is null or arr(i)<>elem then res.extend; res(res.last) := arr(i); end if; end loop; end if; return res; end;
--create or replace function StringArrayType_remove_index(arr in StringArrayType, idx in number) return StringArrayType deterministic is res StringArrayType:=StringArrayType(); begin if arr is null or idx is null then return arr; end if; for i in 1 .. arr.count loop if i<>idx then res.extend; res(res.last) := arr(i); end if; end loop; return res; end;
--create or replace function StringArrayType_slice(arr in StringArrayType, startIdx in number, endIdx in number) return StringArrayType deterministic is res StringArrayType:=StringArrayType(); begin if arr is null or startIdx is null or endIdx is null then return null; end if; for i in startIdx .. least(arr.count,endIdx) loop res.extend; res(res.last) := arr(i); end loop; return res; end;
--create or replace function StringArrayType_replace(arr in StringArrayType, old in varchar2, elem in varchar2) return StringArrayType deterministic is res StringArrayType:=StringArrayType(); begin if arr is null then return null; end if; if old is null then for i in 1 .. arr.count loop res.extend; res(res.last) := coalesce(arr(i),elem); end loop; else for i in 1 .. arr.count loop res.extend; if arr(i) = old then res(res.last) := elem; else res(res.last) := arr(i); end if; end loop; end if; return res; end;
--create or replace function StringArrayType_trim(arr in StringArrayType, elems number) return StringArrayType deterministic is res StringArrayType:=StringArrayType(); begin if arr is null or elems is null then return null; end if; if arr.count < elems then raise_application_error (-20000, 'number of elements to trim must be between 0 and '||arr.count); end if;for i in 1 .. arr.count-elems loop res.extend; res(i) := arr(i); end loop; return res; end;
--create or replace function StringArrayType_fill(elem in varchar2, elems number) return StringArrayType deterministic is res StringArrayType:=StringArrayType(); begin if elems is null then return null; end if; if elems<0 then raise_application_error (-20000, 'number of elements must be greater than or equal to 0'); end if;for i in 1 .. elems loop res.extend; res(i) := elem; end loop; return res; end;
--create or replace function StringArrayType_positions(arr in StringArrayType, elem in varchar2) return sdo_ordinate_array deterministic is res sdo_ordinate_array:=sdo_ordinate_array(); begin if arr is null then return null; end if; if elem is null then for i in 1 .. arr.count loop if arr(i) is null then res.extend; res(res.last):=i; end if; end loop; else for i in 1 .. arr.count loop if arr(i)=elem then res.extend; res(res.last):=i; end if; end loop; end if; return res; end;
--create or replace function StringArrayType_to_string(arr in StringArrayType, sep in varchar2) return varchar2 deterministic is res varchar2(4000):=''; begin if arr is null or sep is null then return null; end if; for i in 1 .. arr.count loop if arr(i) is not null then if length(res)<>0 then res:=res||sep; end if; res:=res||arr(i); end if; end loop; return res; end;


-- Don't forget to commit...
COMMIT;
Loading