| /** |
| * Derby - Class org.apache.derbyTesting.functionTests.tests.lang.SimpleJsonTest |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF 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. |
| */ |
| package org.apache.derbyTesting.functionTests.tests.lang; |
| |
| import java.io.File; |
| import java.sql.Connection; |
| import java.sql.PreparedStatement; |
| import java.sql.ResultSet; |
| import java.sql.SQLException; |
| import java.util.Arrays; |
| |
| import junit.framework.Test; |
| import org.apache.derbyTesting.junit.BaseJDBCTestCase; |
| import org.apache.derbyTesting.junit.BaseTestSuite; |
| import org.apache.derbyTesting.junit.JDBC; |
| import org.apache.derbyTesting.junit.SupportFilesSetup; |
| import org.apache.derbyTesting.junit.TestConfiguration; |
| import org.apache.derbyTesting.functionTests.util.PrivilegedFileOpsForTests; |
| |
| import org.json.simple.JSONArray; |
| import org.json.simple.JSONObject; |
| |
| /** |
| * <p> |
| * Basic test of the optional tool which provides JSON support functions |
| * which use the simple json library from https://code.google.com/p/json-simple/. |
| * </p> |
| */ |
| public class SimpleJsonTest extends BaseJDBCTestCase |
| { |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| // CONSTANTS |
| // |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| private static final String TAB = " "; |
| private static final String USER_ERROR = "38000"; |
| private static final String OUT_OF_RANGE = "22003"; |
| |
| private static final String THERMOSTAT_READINGS = |
| "[\n" + |
| " {\n" + |
| " \"id\": 1,\n" + |
| " \"temperature\": 70.3,\n" + |
| " \"fanOn\": true\n" + |
| " },\n" + |
| " {\n" + |
| " \"id\": 2,\n" + |
| " \"temperature\": 65.5,\n" + |
| " \"fanOn\": false\n" + |
| " }\n" + |
| "]"; |
| |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| // CONSTRUCTORS |
| // |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| public SimpleJsonTest(String name) { |
| super(name); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| // JUnit MACHINERY |
| // |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| public static Test suite() |
| { |
| BaseTestSuite suite = new BaseTestSuite("SimpleJsonTest"); |
| |
| suite.addTest( TestConfiguration.defaultSuite( SimpleJsonTest.class ) ); |
| |
| return new SupportFilesSetup |
| ( |
| suite, |
| new String[] |
| { |
| "functionTests/tests/lang/thermostatReadings.dat", |
| "functionTests/tests/lang/json.dat", |
| } |
| ); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| // JUnit TESTS |
| // |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| public void testBasic_001() throws Exception |
| { |
| Connection conn = getConnection(); |
| |
| // create the json support types and functions |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', true )" ); |
| |
| createSchema_001( conn ); |
| |
| assertResults |
| ( |
| conn, |
| "values prettyPrint( toJSON( " + |
| "'select * from thermostatReadings order by \"id\", \"sampleTime\"' ) )", |
| new String[][] |
| { |
| { |
| "[\n" + |
| " {\n" + |
| " \"fanOn\" : false, \n" + |
| " \"id\" : 1, \n" + |
| " \"sampleTime\" : \"2015-07-08 04:03:20.0\", \n" + |
| " \"temperature\" : 65.5\n" + |
| " }, \n" + |
| " {\n" + |
| " \"fanOn\" : true, \n" + |
| " \"id\" : 1, \n" + |
| " \"sampleTime\" : \"2015-07-08 13:03:20.0\", \n" + |
| " \"temperature\" : 70.1\n" + |
| " }, \n" + |
| " {\n" + |
| " \"fanOn\" : false, \n" + |
| " \"id\" : 2, \n" + |
| " \"sampleTime\" : \"2015-07-08 03:03:20.0\", \n" + |
| " \"temperature\" : 64.5\n" + |
| " }, \n" + |
| " {\n" + |
| " \"fanOn\" : true, \n" + |
| " \"id\" : 2, \n" + |
| " \"sampleTime\" : \"2015-07-08 16:03:20.0\", \n" + |
| " \"temperature\" : 72.1\n" + |
| " }\n" + |
| "]" |
| } |
| }, |
| true |
| ); |
| |
| assertResults |
| ( |
| conn, |
| "values prettyPrint( toJSON( 'select \"id\", max( \"temperature\" ) \"maxTemp\" from thermostatReadings group by \"id\"' ) )", |
| new String[][] |
| { |
| { |
| "[\n" + |
| " {\n" + |
| " \"id\" : 1, \n" + |
| " \"maxTemp\" : 70.1\n" + |
| " }, \n" + |
| " {\n" + |
| " \"id\" : 2, \n" + |
| " \"maxTemp\" : 72.1\n" + |
| " }\n" + |
| "]" |
| } |
| }, |
| true |
| ); |
| |
| assertResults |
| ( |
| conn, |
| "values prettyPrint( toJSON( 'select \"id\", max( \"temperature\" ) \"maxTemp\" from thermostatReadings where \"id\" = ? group by \"id\"', '2' ) )", |
| new String[][] |
| { |
| { |
| "[\n" + |
| " {\n" + |
| " \"id\" : 2, \n" + |
| " \"maxTemp\" : 72.1\n" + |
| " }\n" + |
| "]" |
| } |
| }, |
| true |
| ); |
| |
| dropSchema_001( conn ); |
| |
| // drop the json support types and functions |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', false )" ); |
| } |
| private void createSchema_001( Connection conn ) throws Exception |
| { |
| goodStatement |
| ( |
| conn, |
| "create table thermostatReadings\n" + |
| "(\n" + |
| "\"id\" int,\n" + |
| "\"temperature\" double,\n" + |
| "\"fanOn\" boolean,\n" + |
| "\"sampleTime\" timestamp,\n" + |
| "primary key( \"id\", \"sampleTime\" )\n" + |
| ")\n" |
| ); |
| |
| goodStatement |
| ( |
| conn, |
| "insert into thermostatReadings values\n" + |
| "( 1, 65.5, false, timestamp( '2015-07-08 04:03:20') ),\n" + |
| "( 1, 70.1, true, timestamp( '2015-07-08 13:03:20') ),\n" + |
| "( 2, 64.5, false, timestamp( '2015-07-08 03:03:20') ),\n" + |
| "( 2, 72.1, true, timestamp( '2015-07-08 16:03:20') )\n" |
| ); |
| |
| goodStatement |
| ( |
| conn, |
| "create function prettyPrint( doc JSONArray ) returns varchar( 32672 )\n" + |
| "language java parameter style java no sql\n" + |
| "external name '" + getClass().getName() + ".prettyPrint'\n" |
| ); |
| } |
| private void dropSchema_001( Connection conn ) throws Exception |
| { |
| goodStatement( conn, "drop function prettyPrint" ); |
| goodStatement( conn, "drop table thermostatReadings" ); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * <p> |
| * Test the jsonification of Derby's datatypes. |
| * </p> |
| */ |
| public void testDatatypes_002() throws Exception |
| { |
| Connection conn = getConnection(); |
| |
| // create the json support types and functions |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', true )" ); |
| |
| createSchema_002( conn ); |
| |
| assertResults |
| ( |
| conn, |
| "values( prettyPrint( toJSON( 'select * from all_types order by key_col' ) ) )", |
| new String[][] |
| { |
| { |
| "[\n" + |
| " {\n" + |
| " \"BIGINT_COL\" : 0, \n" + |
| " \"BLOB_COL\" : \"01\", \n" + |
| " \"CHAR_COL\" : \"0 \", \n" + |
| " \"CHAR_FOR_BIT_DATA_COL\" : \"de202020202020202020\", \n" + |
| " \"CLOB_COL\" : \"0\", \n" + |
| " \"DATE_COL\" : \"1994-02-23\", \n" + |
| " \"DECIMAL_COL\" : 0.0, \n" + |
| " \"DOUBLE_COL\" : 0.0, \n" + |
| " \"INT_COL\" : 0, \n" + |
| " \"JSON_ARRAY_COL\" : [\n" + |
| " {\n" + |
| " \"A\" : 1, \n" + |
| " \"B\" : true\n" + |
| " }, \n" + |
| " {\n" + |
| " \"A\" : 2, \n" + |
| " \"B\" : false\n" + |
| " }\n" + |
| " ], \n" + |
| " \"KEY_COL\" : 0, \n" + |
| " \"LONG_VARCHAR_COL\" : \"0\", \n" + |
| " \"LONG_VARCHAR_FOR_BIT_DATA_COL\" : \"de\", \n" + |
| " \"NUMERIC_COL\" : 0.0, \n" + |
| " \"PRICE_COL\" : \"Price( USD, 9.99000, 2009-10-16 14:24:43.0 )\", \n" + |
| " \"REAL_COL\" : 0.0, \n" + |
| " \"SMALLINT_COL\" : 0, \n" + |
| " \"TIMESTAMP_COL\" : \"1962-09-23 03:23:34.234\", \n" + |
| " \"TIME_COL\" : \"15:09:02\", \n" + |
| " \"VARCHAR_COL\" : \"0\", \n" + |
| " \"VARCHAR_FOR_BIT_DATA_COL\" : \"de\"\n" + |
| " }, \n" + |
| " {\n" + |
| " \"BIGINT_COL\" : null, \n" + |
| " \"BLOB_COL\" : null, \n" + |
| " \"CHAR_COL\" : null, \n" + |
| " \"CHAR_FOR_BIT_DATA_COL\" : null, \n" + |
| " \"CLOB_COL\" : null, \n" + |
| " \"DATE_COL\" : null, \n" + |
| " \"DECIMAL_COL\" : null, \n" + |
| " \"DOUBLE_COL\" : null, \n" + |
| " \"INT_COL\" : null, \n" + |
| " \"JSON_ARRAY_COL\" : null, \n" + |
| " \"KEY_COL\" : 1, \n" + |
| " \"LONG_VARCHAR_COL\" : null, \n" + |
| " \"LONG_VARCHAR_FOR_BIT_DATA_COL\" : null, \n" + |
| " \"NUMERIC_COL\" : null, \n" + |
| " \"PRICE_COL\" : null, \n" + |
| " \"REAL_COL\" : null, \n" + |
| " \"SMALLINT_COL\" : null, \n" + |
| " \"TIMESTAMP_COL\" : null, \n" + |
| " \"TIME_COL\" : null, \n" + |
| " \"VARCHAR_COL\" : null, \n" + |
| " \"VARCHAR_FOR_BIT_DATA_COL\" : null\n" + |
| " }\n" + |
| "]" } |
| }, |
| true |
| ); |
| |
| dropSchema_002( conn ); |
| |
| // drop the json support types and functions |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', false )" ); |
| } |
| private void createSchema_002( Connection conn ) throws Exception |
| { |
| goodStatement |
| ( |
| conn, |
| "create type Price external name 'org.apache.derbyTesting.functionTests.tests.lang.Price' language java" |
| ); |
| goodStatement |
| ( |
| conn, |
| "create function makePrice( currencyCode char( 3 ), amount decimal( 31, 5 ), timeInstant Timestamp )\n" + |
| "returns Price language java parameter style java no sql\n" + |
| "external name 'org.apache.derbyTesting.functionTests.tests.lang.Price.makePrice'\n" |
| ); |
| goodStatement |
| ( |
| conn, |
| "create function makeSimpleBlob( ) returns blob\n" + |
| "language java parameter style java no sql deterministic\n" + |
| "external name 'org.apache.derbyTesting.functionTests.tests.lang.BooleanValuesTest.makeSimpleBlob'\n" |
| ); |
| goodStatement |
| ( |
| conn, |
| "create table dummy( a int, b boolean )" |
| ); |
| goodStatement |
| ( |
| conn, |
| "insert into dummy values ( 1, true ), ( 2, false )" |
| ); |
| goodStatement |
| ( |
| conn, |
| "create table all_types\n" + |
| "(\n" + |
| " key_col int,\n" + |
| " bigint_col BIGINT,\n" + |
| " blob_col BLOB(2147483647),\n" + |
| " char_col CHAR(10),\n" + |
| " char_for_bit_data_col CHAR (10) FOR BIT DATA,\n" + |
| " clob_col CLOB(2147483647),\n" + |
| " date_col DATE,\n" + |
| " decimal_col DECIMAL(5,2),\n" + |
| " real_col REAL,\n" + |
| " double_col DOUBLE,\n" + |
| " int_col INTEGER,\n" + |
| " long_varchar_col LONG VARCHAR,\n" + |
| " long_varchar_for_bit_data_col LONG VARCHAR FOR BIT DATA,\n" + |
| " numeric_col NUMERIC(5,2),\n" + |
| " smallint_col SMALLINT,\n" + |
| " time_col TIME,\n" + |
| " timestamp_col TIMESTAMP,\n" + |
| " varchar_col VARCHAR(10),\n" + |
| " varchar_for_bit_data_col VARCHAR (10) FOR BIT DATA,\n" + |
| " price_col price,\n" + |
| " json_array_col jsonArray\n" + |
| ")\n" |
| ); |
| goodStatement |
| ( |
| conn, |
| "insert into all_types( key_col ) values ( 1 )" |
| ); |
| goodStatement |
| ( |
| conn, |
| "insert into all_types\n" + |
| "(\n" + |
| " key_col,\n" + |
| " bigint_col,\n" + |
| " blob_col,\n" + |
| " char_col,\n" + |
| " char_for_bit_data_col,\n" + |
| " clob_col,\n" + |
| " date_col,\n" + |
| " decimal_col,\n" + |
| " real_col,\n" + |
| " double_col,\n" + |
| " int_col,\n" + |
| " long_varchar_col,\n" + |
| " long_varchar_for_bit_data_col,\n" + |
| " numeric_col,\n" + |
| " smallint_col,\n" + |
| " time_col,\n" + |
| " timestamp_col,\n" + |
| " varchar_col,\n" + |
| " varchar_for_bit_data_col,\n" + |
| " price_col,\n" + |
| " json_array_col\n" + |
| ")\n" + |
| "values\n" + |
| "(\n" + |
| " 0,\n" + |
| " 0,\n" + |
| " makeSimpleBlob(),\n" + |
| " '0',\n" + |
| " X'DE',\n" + |
| " '0',\n" + |
| " date('1994-02-23'),\n" + |
| " 0.00,\n" + |
| " 0.0,\n" + |
| " 0.0,\n" + |
| " 0,\n" + |
| " '0',\n" + |
| " X'DE',\n" + |
| " 0.00,\n" + |
| " 0,\n" + |
| " time('15:09:02'),\n" + |
| " timestamp('1962-09-23 03:23:34.234'),\n" + |
| " '0',\n" + |
| " X'DE',\n" + |
| " makePrice( 'USD', cast( 9.99 as decimal( 31, 5 ) ), timestamp('2009-10-16 14:24:43') ),\n" + |
| " toJSON( 'select * from dummy order by a' ) \n" + |
| ")\n" |
| ); |
| goodStatement |
| ( |
| conn, |
| "create function prettyPrint( doc JSONArray ) returns varchar( 32672 )\n" + |
| "language java parameter style java no sql\n" + |
| "external name 'org.apache.derbyTesting.functionTests.tests.lang.SimpleJsonTest.prettyPrint'\n" |
| ); |
| } |
| private void dropSchema_002( Connection conn ) throws Exception |
| { |
| goodStatement |
| ( |
| conn, |
| "drop function makePrice" |
| ); |
| goodStatement |
| ( |
| conn, |
| "drop function makeSimpleBlob" |
| ); |
| goodStatement |
| ( |
| conn, |
| "drop table all_types" |
| ); |
| goodStatement |
| ( |
| conn, |
| "drop type price restrict" |
| ); |
| goodStatement |
| ( |
| conn, |
| "drop function prettyPrint" |
| ); |
| |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * <p> |
| * Test errors. |
| * </p> |
| */ |
| public void testNegative_003() throws Exception |
| { |
| Connection conn = getConnection(); |
| |
| // can't load the tool redundantly |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', true )" ); |
| |
| expectExecutionError |
| ( |
| conn, |
| USER_ERROR, |
| "call syscs_util.syscs_register_tool( 'simpleJson', true )" |
| ); |
| |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', false )" ); |
| |
| // can't unload the tool redundantly |
| expectExecutionError |
| ( |
| conn, |
| USER_ERROR, |
| "call syscs_util.syscs_register_tool( 'simpleJson', false )" |
| ); |
| |
| // need to specify all ? parameters |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', true )" ); |
| |
| expectExecutionError |
| ( |
| conn, |
| USER_ERROR, |
| "values( toJSON( 'select * from sys.systables where tablename = ?' ) )" |
| ); |
| |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', false )" ); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * <p> |
| * Test the SimpleJsonVTI. |
| * </p> |
| */ |
| public void testVTI_004() throws Exception |
| { |
| Connection conn = getConnection(); |
| |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', true )" ); |
| |
| // declare a table function for reading a string |
| goodStatement |
| ( |
| conn, |
| "create function thermostatReadings( jsonDocument JSONArray )\n" + |
| "returns table\n" + |
| "(\n" + |
| "\"id\" int,\n" + |
| "\"temperature\" float,\n" + |
| "\"fanOn\" boolean\n" + |
| ")\n" + |
| "language java parameter style derby_jdbc_result_set contains sql\n" + |
| "external name 'org.apache.derby.optional.api.SimpleJsonVTI.readArray'\n" |
| ); |
| |
| PreparedStatement ps; |
| ResultSet rs; |
| |
| // turn a JSON document string into a ResultSet |
| ps = conn.prepareStatement |
| ( |
| "select * from table\n" + |
| "( thermostatReadings( readArrayFromString(?) ) ) t order by \"id\"" |
| ); |
| ps.setString( 1, THERMOSTAT_READINGS ); |
| rs = ps.executeQuery(); |
| assertResults |
| ( |
| rs, |
| new String[][] |
| { |
| { "1", "70.3", "true" }, |
| { "2", "65.5", "false" } |
| }, |
| true |
| ); |
| rs.close(); |
| ps.close(); |
| |
| // make a ResultSet out of a file containing JSON text |
| File inputFile = SupportFilesSetup.getReadOnly( "thermostatReadings.dat" ); |
| String[][] fileReadings = new String[][] |
| { |
| { "1", "70.3", "true" }, |
| { "2", "65.5", "false" }, |
| { "3", "60.5", "false" }, |
| }; |
| ps = conn.prepareStatement |
| ( |
| "select * from table\n" + |
| "( thermostatReadings( readArrayFromFile( ?, 'UTF-8' ) ) ) t order by \"id\"" |
| ); |
| ps.setString( 1, PrivilegedFileOpsForTests.getAbsolutePath( inputFile ) ); |
| rs = ps.executeQuery(); |
| assertResults(rs, fileReadings, true ); |
| rs.close(); |
| ps.close(); |
| |
| // make a ResultSet out of an URL which points to a file containing JSON text |
| ps = conn.prepareStatement |
| ( |
| "select * from table\n" + |
| "( thermostatReadings( readArrayFromURL( ?, 'UTF-8' ) ) ) t order by \"id\"" |
| ); |
| String inputFileURL = PrivilegedFileOpsForTests.toURI(inputFile ).toURL().toString(); |
| ps.setString( 1, inputFileURL); |
| rs = ps.executeQuery(); |
| assertResults(rs, fileReadings, true ); |
| rs.close(); |
| ps.close(); |
| |
| goodStatement( conn, "drop function thermostatReadings" ); |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', false )" ); |
| } |
| |
| /** |
| * <p> |
| * Test the datatypes understood by SimpleJsonVTI. |
| * </p> |
| */ |
| public void testVTIdatatypes005() throws Exception |
| { |
| Connection conn = getConnection(); |
| |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', true )" ); |
| |
| vetDatatype_005 |
| ( |
| conn, |
| "smallint", |
| new String[][] |
| { |
| { "abc","true", "127" }, |
| { "def", "false", "1" }, |
| { "ghi", null, "345" }, |
| { "lmn", "true", "-1" }, |
| } |
| ); |
| vetDatatype_005 |
| ( |
| conn, |
| "int", |
| new String[][] |
| { |
| { "abc","true", "127" }, |
| { "def", "false", "1" }, |
| { "ghi", null, "345" }, |
| { "lmn", "true", "-1" }, |
| } |
| ); |
| vetDatatype_005 |
| ( |
| conn, |
| "bigint", |
| new String[][] |
| { |
| { "abc","true", "127" }, |
| { "def", "false", "1" }, |
| { "ghi", null, "345" }, |
| { "lmn", "true", "9223372036854775807" }, |
| } |
| ); |
| vetDatatype_005 |
| ( |
| conn, |
| "float", |
| new String[][] |
| { |
| { "abc","true", "127.0" }, |
| { "def", "false", "1.2" }, |
| { "ghi", null, "345.67" }, |
| { "lmn", "true", "9.223372036854776E18" }, |
| } |
| ); |
| vetDatatype_005 |
| ( |
| conn, |
| "double", |
| new String[][] |
| { |
| { "abc","true", "127.0" }, |
| { "def", "false", "1.2" }, |
| { "ghi", null, "345.67" }, |
| { "lmn", "true", "9.223372036854776E18" }, |
| } |
| ); |
| |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', false )" ); |
| } |
| private void vetDatatype_005 |
| ( |
| Connection conn, |
| String datatype, |
| String[][] expectedResults |
| ) |
| throws Exception |
| { |
| createFunction_005( conn, datatype ); |
| |
| PreparedStatement ps = conn.prepareStatement |
| ( |
| "select * from table\n" + |
| "( f_" + datatype + "( readArrayFromFile( ?, 'UTF-8' ) )) t\n" |
| ); |
| File inputFile = SupportFilesSetup.getReadOnly( "json.dat" ); |
| ps.setString( 1, PrivilegedFileOpsForTests.getAbsolutePath( inputFile ) ); |
| |
| ResultSet rs; |
| |
| rs = ps.executeQuery(); |
| assertResults(rs, expectedResults, true ); |
| rs.close(); |
| |
| // the first two rows have numeric values which won't raise |
| // truncation exceptions when fetched into tinyint |
| rs = ps.executeQuery(); |
| rs.next(); |
| assertEquals( (byte) 127, rs.getByte( "NUM_COL" ) ); |
| rs.next(); |
| assertEquals( (byte) 1, rs.getByte( "NUM_COL" ) ); |
| rs.close(); |
| |
| ps.close(); |
| |
| dropFunction_005( conn, datatype ); |
| } |
| private void createFunction_005( Connection conn, String datatype ) |
| throws Exception |
| { |
| goodStatement |
| ( |
| conn, |
| "create function f_" + datatype + "( jsonArray JSONArray )\n" + |
| "returns table\n" + |
| "(\n" + |
| " str_col varchar( 10 ),\n" + |
| " bool_col boolean,\n" + |
| " num_col " + datatype + "\n" + |
| ")\n" + |
| "language java parameter style derby_jdbc_result_set contains sql\n" + |
| "external name 'org.apache.derby.optional.api.SimpleJsonVTI.readArray'\n" |
| ); |
| } |
| private void dropFunction_005( Connection conn, String datatype ) |
| throws Exception |
| { |
| goodStatement( conn, "drop function f_" + datatype ); |
| } |
| |
| /** |
| * <p> |
| * Test the arrayToClob() function. |
| * </p> |
| */ |
| public void testArrayToClob_006() throws Exception |
| { |
| Connection conn = getConnection(); |
| |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', true )" ); |
| goodStatement( conn, "create table employee( fullName varchar( 100 ) )" ); |
| goodStatement( conn, "create table docs( stringDoc varchar( 32672 ) )" ); |
| goodStatement( conn, "insert into employee values ( 'Fred Flintstone' ), ( 'Barney Rubble' )" ); |
| goodStatement( conn, "insert into docs values( arrayToClob( toJSON( 'select * from employee' ) ) )" ); |
| |
| assertResults |
| ( |
| conn, |
| "select * from docs", |
| new String[][] |
| { |
| { |
| "[{\"FULLNAME\":\"Fred Flintstone\"},{\"FULLNAME\":\"Barney Rubble\"}]" |
| } |
| }, |
| true |
| ); |
| |
| goodStatement( conn, "drop table docs" ); |
| goodStatement( conn, "drop table employee" ); |
| goodStatement( conn, "call syscs_util.syscs_register_tool( 'simpleJson', false )" ); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| // FUNCTIONS |
| // |
| /////////////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * <p> |
| * Pretty-print a JSONArray. |
| * </p> |
| */ |
| public static String prettyPrint( JSONArray array ) |
| { |
| StringBuilder buffer = new StringBuilder(); |
| |
| prettyPrintArray( buffer, 0, array ); |
| |
| return buffer.toString(); |
| } |
| |
| private static void prettyPrintArray |
| ( |
| StringBuilder buffer, |
| int indentLevel, |
| JSONArray array |
| ) |
| { |
| buffer.append( "[" ); |
| int cellCount = array.size(); |
| if ( cellCount > 0 ) |
| { |
| for ( int i = 0; i < cellCount; i++ ) |
| { |
| if ( i > 0 ) { buffer.append( ", " ); } |
| indent( buffer, indentLevel + 1 ); |
| prettyPrint( buffer, indentLevel + 1, array.get( i ) ); |
| } |
| indent( buffer, indentLevel ); |
| } |
| buffer.append( "]" ); |
| } |
| |
| private static void prettyPrintObject |
| ( |
| StringBuilder buffer, |
| int indentLevel, |
| JSONObject obj |
| ) |
| { |
| buffer.append( "{" ); |
| int keyCount = obj.size(); |
| if ( keyCount > 0 ) |
| { |
| // alphabetize the keys |
| Object[] keys = obj.keySet().toArray(); |
| Arrays.sort( keys ); |
| for ( int i = 0; i < keyCount; i++ ) |
| { |
| Object key = keys[ i ]; |
| if ( i > 0 ) { buffer.append( ", " ); } |
| indent( buffer, indentLevel + 1 ); |
| buffer.append( doubleQuote( (String) key ) ); |
| buffer.append( " : " ); |
| prettyPrint( buffer, indentLevel + 1, obj.get( key ) ); |
| } |
| indent( buffer, indentLevel ); |
| } |
| buffer.append( "}" ); |
| } |
| |
| private static void prettyPrint |
| ( |
| StringBuilder buffer, |
| int indentLevel, |
| Object obj |
| ) |
| { |
| if ( obj == null ) { buffer.append( "null" ); } |
| else if ( obj instanceof JSONArray ) |
| { prettyPrintArray( buffer, indentLevel, (JSONArray) obj ); } |
| else if ( obj instanceof JSONObject ) |
| { prettyPrintObject( buffer, indentLevel, (JSONObject) obj ); } |
| else if ( (obj instanceof Number) || (obj instanceof Boolean) ) |
| { buffer.append( obj.toString() ); } |
| else { buffer.append( doubleQuote( obj.toString() ) ); } |
| } |
| |
| private static void indent( StringBuilder buffer, int indentLevel ) |
| { |
| buffer.append( "\n" ); |
| for ( int i = 0; i < indentLevel; i++ ) { buffer.append( TAB ); } |
| } |
| |
| private static String doubleQuote( String raw ) |
| { |
| return "\"" + raw + "\""; |
| } |
| } |