/*
* Licensed to Crate under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership. Crate licenses this file
* to you 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.
*
* However, if you have executed another commercial license agreement
* with Crate these terms will supersede the license and you may use the
* software solely pursuant to the terms of the relevant commercial
* agreement.
*/
package io.crate.protocols.postgres.types;
import org.hamcrest.Matchers;
import org.hamcrest.core.Is;
import org.junit.Test;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
public class PGArrayTest {
private PGArray pgArray = PGArray.INT4_ARRAY;
@Test
public void testEncodeUTF8Text() throws Exception {
// 1-dimension array
byte[] bytes = pgArray.encodeAsUTF8Text(new Object[] { 10, 20 });
String s = new String(bytes, StandardCharsets.UTF_8);
assertThat(s, is("{\"10\",\"20\"}"));
// 3-dimension array
bytes = pgArray.encodeAsUTF8Text(new Object[][][] {{{1, 2}, {3, 4}}, {{5, 6}, {7}}});
s = new String(bytes, StandardCharsets.UTF_8);
assertThat(s, is("{{{\"1\",\"2\"},{\"3\",\"4\"}},{{\"5\",\"6\"},{\"7\"}}}"));
}
@Test
public void testArrayWithNullValues() throws Exception {
Object[] array = {10, null, 20};
byte[] bytes = pgArray.encodeAsUTF8Text(array);
String s = new String(bytes, StandardCharsets.UTF_8);
assertThat(s, is("{\"10\",NULL,\"20\"}"));
Object o = pgArray.decodeUTF8Text(bytes);
assertThat(((Object[]) o), is(array));
}
@SuppressWarnings("unchecked")
@Test
public void testJsonArrayEncodeDecode() throws Exception {
// 1-dimension array
// Decode
String s = "{\"{\"names\":[\"Arthur\",\"Trillian\"]}\",\"{\"names\":[\"Ford\",\"Slarti\"]}\"}";
Object[] values = (Object[]) PGArray.JSON_ARRAY.decodeUTF8Text(s.getBytes(StandardCharsets.UTF_8));
List<String> names = (List<String>) ((Map) values[0]).get("names");
assertThat(names, Matchers.contains("Arthur", "Trillian"));
names = (List<String>) ((Map) values[1]).get("names");
assertThat(names, Matchers.contains("Ford", "Slarti"));
// Encode
byte[] bytes = PGArray.JSON_ARRAY.encodeAsUTF8Text(values);
s = new String(bytes, StandardCharsets.UTF_8);
assertThat(s, is(s));
// 3-dimension array
// Decode
s = "{{{\"{\"names\":[\"A\",\"B\"]}\",\"{\"names\":[\"C\",\"D\"]}\"}," +
"{\"{\"names\":[\"E\",\"F\"]}\",\"{\"names\":[\"G\",\"H\"]}\"}}," +
"{{\"{\"names\":[\"I\",\"J\"]}\",\"{\"names\":[\"K\",\"L\"]}\"}," +
"{\"{\"names\":[\"M\",\"N\"]}\",\"{\"names\":[\"O\",\"P\"]}\"}}}";
values = (Object[]) PGArray.JSON_ARRAY.decodeUTF8Text(s.getBytes(StandardCharsets.UTF_8));
names = (List<String>) ((Map) ((Object[])((Object[])values[0])[0])[0]).get("names");
assertThat(names, Matchers.contains("A", "B"));
names = (List<String>) ((Map) ((Object[])((Object[])values[0])[0])[1]).get("names");
assertThat(names, Matchers.contains("C", "D"));
names = (List<String>) ((Map) ((Object[])((Object[])values[0])[1])[0]).get("names");
assertThat(names, Matchers.contains("E", "F"));
names = (List<String>) ((Map) ((Object[])((Object[])values[0])[1])[1]).get("names");
assertThat(names, Matchers.contains("G", "H"));
names = (List<String>) ((Map) ((Object[])((Object[])values[1])[0])[0]).get("names");
assertThat(names, Matchers.contains("I", "J"));
names = (List<String>) ((Map) ((Object[])((Object[])values[1])[0])[1]).get("names");
assertThat(names, Matchers.contains("K", "L"));
names = (List<String>) ((Map) ((Object[])((Object[])values[1])[1])[0]).get("names");
assertThat(names, Matchers.contains("M", "N"));
names = (List<String>) ((Map) ((Object[])((Object[])values[1])[1])[1]).get("names");
assertThat(names, Matchers.contains("O", "P"));
// Encode
bytes = PGArray.JSON_ARRAY.encodeAsUTF8Text(values);
s = new String(bytes, StandardCharsets.UTF_8);
assertThat(s, is(s));
}
@Test
@SuppressWarnings("unchecked")
public void testDecodeEncodeEscapedJson() throws Exception {
// Decode
String s = "{\"{\\\"names\\\":[\\\"Arthur\\\",\\\"Trillian\\\"]}\",\"{\\\"names\\\":[\\\"Ford\\\",\\\"Slarti\\\"]}\"}";
Object[] values = (Object[]) PGArray.JSON_ARRAY.decodeUTF8Text(s.getBytes(StandardCharsets.UTF_8));
List<String> names = (List<String>) ((Map) values[0]).get("names");
assertThat(names, Matchers.contains("Arthur", "Trillian"));
names = (List<String>) ((Map) values[1]).get("names");
assertThat(names, Matchers.contains("Ford", "Slarti"));
// Encode
byte[] bytes = PGArray.JSON_ARRAY.encodeAsUTF8Text(values);
s = new String(bytes, StandardCharsets.UTF_8);
assertThat(s, is("{\"{\\\"names\\\":[\\\"Arthur\\\",\\\"Trillian\\\"]}\"," +
"\"{\\\"names\\\":[\\\"Ford\\\",\\\"Slarti\\\"]}\"}"));
}
@Test
public void testDecodeUTF8Text() throws Exception {
// 1-dimension array
Object o = pgArray.decodeUTF8Text("{\"10\",\"20\"}".getBytes(StandardCharsets.UTF_8));
assertThat((Object[]) o, is(new Object[] {10, 20}));
// 2-dimension array
o = pgArray.decodeUTF8Text("{{\"1\",NULL,\"2\"},{NULL,\"3\",\"4\"}}".getBytes(StandardCharsets.UTF_8));
assertThat(((Object[]) o), Is.<Object[]>is(new Object[][] {{1, null, 2}, {null, 3, 4}}));
// 3-dimension array
o = pgArray.decodeUTF8Text("{{{\"1\",NULL,\"2\"},{NULL,\"3\",\"4\"}},{{\"5\",NULL,\"6\"},{\"7\"}}".getBytes(StandardCharsets.UTF_8));
assertThat(((Object[]) o), Is.<Object[]>is(new Object[][][] {{{1, null, 2}, {null, 3, 4}}, {{5, null, 6}, {7}}}));
}
}