diff --git a/vertx-oracle-client/src/test/java/io/vertx/oracleclient/test/OracleArrayTest.java b/vertx-oracle-client/src/test/java/io/vertx/oracleclient/test/OracleArrayTest.java new file mode 100644 index 000000000..c860c601f --- /dev/null +++ b/vertx-oracle-client/src/test/java/io/vertx/oracleclient/test/OracleArrayTest.java @@ -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()); + } +} diff --git a/vertx-oracle-client/src/test/resources/tck/import.sql b/vertx-oracle-client/src/test/resources/tck/import.sql index 406cb38fa..e862ea2c5 100644 --- a/vertx-oracle-client/src/test/resources/tck/import.sql +++ b/vertx-oracle-client/src/test/resources/tck/import.sql @@ -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.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;