Package com.foundationdb.ais.protobuf

Source Code of com.foundationdb.ais.protobuf.ProtobufReaderWriterTest

/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.foundationdb.ais.protobuf;

import com.foundationdb.ais.CAOIBuilderFiller;
import com.foundationdb.ais.model.AISBuilder;
import com.foundationdb.ais.model.AkibanInformationSchema;
import com.foundationdb.ais.model.Column;
import com.foundationdb.ais.model.Index;
import com.foundationdb.ais.model.IndexColumn;
import com.foundationdb.ais.model.Join;
import com.foundationdb.ais.model.JoinColumn;
import com.foundationdb.ais.model.Parameter;
import com.foundationdb.ais.model.Routine;
import com.foundationdb.ais.model.Sequence;
import com.foundationdb.ais.model.SQLJJar;
import com.foundationdb.ais.model.TableIndex;
import com.foundationdb.ais.model.Table;
import com.foundationdb.ais.model.TableName;
import com.foundationdb.ais.model.aisb2.AISBBasedBuilder;
import com.foundationdb.ais.model.aisb2.NewAISBuilder;
import com.foundationdb.server.collation.AkCollatorFactory;
import com.foundationdb.server.error.ProtobufReadException;
import com.foundationdb.server.error.ProtobufWriteException;
import com.foundationdb.server.store.format.DummyStorageFormatRegistry;
import com.foundationdb.server.store.format.StorageFormatRegistry;
import com.foundationdb.server.store.format.TestStorageDescription;
import com.foundationdb.server.types.TInstance;
import com.foundationdb.server.types.common.types.StringAttribute;
import com.foundationdb.server.types.common.types.StringFactory;
import com.foundationdb.server.types.common.types.TypesTranslator;
import com.foundationdb.server.types.mcompat.mtypes.MTypesTranslator;
import com.foundationdb.server.types.service.TestTypesRegistry;
import com.foundationdb.server.types.service.TypesRegistry;
import org.junit.Test;

import java.nio.ByteBuffer;

import static com.foundationdb.ais.AISComparator.compareAndAssert;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

public class ProtobufReaderWriterTest {
    private final String SCHEMA = "test";
    private final String identifier = "test";

    @Test
    public void empty() {
        final AkibanInformationSchema inAIS = new AkibanInformationSchema();
        inAIS.freeze();
        final AkibanInformationSchema outAIS = writeAndRead(inAIS);
        compareAndAssert(inAIS, outAIS, false);
    }

    @Test
    public void caoi() {
        final AkibanInformationSchema inAIS = CAOIBuilderFiller.createAndFillBuilder(SCHEMA).ais();
        final AkibanInformationSchema outAIS = writeAndRead(inAIS);
        compareAndAssert(inAIS, outAIS, false);
    }
   
    @Test
    public void caoiWithGroupIndex() {
        NewAISBuilder builder = CAOIBuilderFiller.createAndFillBuilder(SCHEMA);
        builder.groupIndex("iprice_odate", Index.JoinType.RIGHT).
                on(CAOIBuilderFiller.ITEM_TABLE, "unit_price").
                and(CAOIBuilderFiller.ORDER_TABLE, "order_date");
       
        final AkibanInformationSchema inAIS = builder.ais();
        final AkibanInformationSchema outAIS = writeAndRead(inAIS);
        compareAndAssert(inAIS, outAIS, false);
    }

    @Test
    public void caoiWithView() {
        NewAISBuilder builder = CAOIBuilderFiller.createAndFillBuilder(SCHEMA);
        builder.view("recent_orders").
            definition("CREATE VIEW recent_order AS SELECT * FROM order WHERE order_date > CURRENT_DATE - INTERVAL '30' DAY").
            references(CAOIBuilderFiller.ORDER_TABLE).
            colBigInt("order_id", false).
            colBigInt("customer_id", false).
                colInt("order_date", false);
        final AkibanInformationSchema inAIS = builder.ais();
        final AkibanInformationSchema outAIS = writeAndRead(inAIS);
        compareAndAssert(inAIS, outAIS, false);
    }

    @Test
    public void nonDefaultCharsetAndCollations() {
        // AIS char/col not serialized (will be on Schema when that exists)
        final AkibanInformationSchema inAIS = CAOIBuilderFiller.createAndFillBuilder(SCHEMA).ais(false);
        inAIS.getTable(SCHEMA, CAOIBuilderFiller.ORDER_TABLE).
                setCharsetAndCollation("utf16", "sv_se_ci");
        Column column = inAIS.getTable(SCHEMA, CAOIBuilderFiller.CUSTOMER_TABLE).getColumn("customer_name");
        TInstance type = column.getType();
        type = type.typeClass().instance(
                        type.attribute(StringAttribute.MAX_LENGTH),
                        StringFactory.Charset.LATIN1.ordinal(),
                        AkCollatorFactory.getAkCollator("en_us").getCollationId(),
                        type.nullability());
        column.setType(type);
        inAIS.freeze();
       
        final AkibanInformationSchema outAIS = writeAndRead(inAIS);
        compareAndAssert(inAIS, outAIS, false);
    }

    /*
     * Stubbed out parent, similar to how table creation from the adapter works
     */
    @Test
    public void partialParentWithFullChild() {
        final AkibanInformationSchema inAIS = new AkibanInformationSchema();
       
        Table stubCustomer = Table.create(inAIS, SCHEMA, "c", 1);
        TInstance bigint = typesRegistry().getTypeClass("MCOMPAT", "BIGINT").instance(false);
        Column cId = Column.create(stubCustomer, "id", 2, bigint);

        Table realOrder = Table.create(inAIS, SCHEMA, "o", 2);
        Column oId = Column.create(realOrder, "oid", 0, bigint);
        Column oCid = Column.create(realOrder, "cid", 1, bigint);
        TInstance date = typesRegistry().getTypeClass("MCOMPAT", "DATE").instance(true);
        Column.create(realOrder, "odate", 2, date);
        Index orderPK = TableIndex.create(inAIS, realOrder, Index.PRIMARY, 0, true, true, new TableName(SCHEMA, "pkey"));
        IndexColumn.create(orderPK, oId, 0, true, null);
        Index akFk = TableIndex.create(inAIS, realOrder, "_fk1", 1, false, false);
        IndexColumn.create(akFk, oCid, 0, true, null);
        Join coJoin = Join.create(inAIS, "co", stubCustomer, realOrder);
        JoinColumn.create(coJoin, cId, oCid);

        final AkibanInformationSchema outAIS = writeAndRead(inAIS);
        compareAndAssert(inAIS, outAIS, false);
    }

    /*
     * Stubbed out table, similar to how index creation from the adapter works
     */
    @Test
    public void partialTableWithIndexes() {
        final AkibanInformationSchema inAIS = new AkibanInformationSchema();

        Table stubCustomer = Table.create(inAIS, SCHEMA, "c", 1);
        TInstance varchar32 = typesRegistry().getTypeClass("MCOMPAT", "VARCHAR").instance(32, true);
        Column cFirstName = Column.create(stubCustomer, "first_name", 3, varchar32);
        Column cLastName = Column.create(stubCustomer, "last_name", 4, varchar32);
        TInstance int_null = typesRegistry().getTypeClass("MCOMPAT", "INT").instance(true);
        Column cPayment = Column.create(stubCustomer, "payment", 6, int_null);
        Index iName = TableIndex.create(inAIS, stubCustomer, "name", 2, false, false);
        IndexColumn.create(iName, cLastName, 0, true, null);
        IndexColumn.create(iName, cFirstName, 1, true, null);
        Index iPayment = TableIndex.create(inAIS, stubCustomer, "payment", 3, false, false);
        IndexColumn.create(iPayment, cPayment, 0, true, null);
       
        final AkibanInformationSchema outAIS = writeAndRead(inAIS);
        compareAndAssert(inAIS, outAIS, false);
    }

    @Test
    public void caoiWithFullComparison() {
        final AkibanInformationSchema inAIS = CAOIBuilderFiller.createAndFillBuilder(SCHEMA).ais();
        final AkibanInformationSchema outAIS = writeAndRead(inAIS);
        compareAndAssert(inAIS, outAIS, true);
    }

    @Test(expected=ProtobufReadException.class)
    public void missingRootTable() {
        final AkibanInformationSchema inAIS = CAOIBuilderFiller.createAndFillBuilder(SCHEMA).ais(false);
        inAIS.getTables().remove(TableName.create(SCHEMA, CAOIBuilderFiller.CUSTOMER_TABLE));
        inAIS.getSchema(SCHEMA).getTables().remove(CAOIBuilderFiller.CUSTOMER_TABLE);
        writeAndRead(inAIS);
    }

    @Test(expected=ProtobufReadException.class)
    public void readBufferTooSmall() {
        ByteBuffer bb = ByteBuffer.allocate(4096);
        final AkibanInformationSchema inAIS = CAOIBuilderFiller.createAndFillBuilder(SCHEMA).ais();
        ProtobufWriter writer = new ProtobufWriter();
        writer.save(inAIS);
        writer.serialize(bb);

        bb.flip();
        bb.limit(bb.limit() / 2);
        new ProtobufReader(typesRegistry(), storageFormatRegistry()).loadBuffer(bb);
    }

    @Test(expected=ProtobufWriteException.class)
    public void writeBufferTooSmall() {
        ByteBuffer bb = ByteBuffer.allocate(10);
        final AkibanInformationSchema inAIS = CAOIBuilderFiller.createAndFillBuilder(SCHEMA).ais();
        ProtobufWriter writer = new ProtobufWriter();
        writer.save(inAIS);
        writer.serialize(bb);
    }

    // bug971833
    @Test
    public void tableWithNoDeclaredPK() {
        // CREATE TABLE t1(valid BOOLEAN, state CHAR(2))
        final String TABLE = "t1";
        AISBuilder builder = new AISBuilder();
        builder.table(SCHEMA, TABLE);
        builder.column(SCHEMA, TABLE, "valid", 0, typesRegistry().getTypeClass("MCOMPAT", "TINYINT").instance(true), false, null, null);
        builder.column(SCHEMA, TABLE, "state", 1, typesRegistry().getTypeClass("MCOMPAT", "CHAR").instance(2, true), false, null, null);
        builder.createGroup(TABLE, SCHEMA);
        builder.addTableToGroup(TABLE, SCHEMA, TABLE);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();

        // AIS does not have to be validate-able to be serialized (this is how it comes from adapter)
        final AkibanInformationSchema inAIS = builder.akibanInformationSchema();
        final Table t1_1 = inAIS.getTable(SCHEMA, TABLE);
        assertNull("Source table should not have declared PK", t1_1.getPrimaryKey());
        assertNotNull("Source table should have internal PK", t1_1.getPrimaryKeyIncludingInternal());

        // Serialized AIS did not create an internal column, PK
        AkibanInformationSchema outAIS = writeAndRead(inAIS);
        Table t1_2 = outAIS.getTable(SCHEMA, TABLE);
        assertNull("Deserialized should not have declared PK", t1_2.getPrimaryKey());
        assertNotNull("Deserialized should have internal PK", t1_2.getPrimaryKeyIncludingInternal());

        compareAndAssert(inAIS, outAIS, false);

        // Now add an internal PK and run through again
        t1_1.endTable(builder.getNameGenerator());
        assertNull("Source table should not have declared PK", t1_1.getPrimaryKey());
        assertNotNull("Source table should have internal PK", t1_1.getPrimaryKeyIncludingInternal());

        outAIS = writeAndRead(inAIS);
        t1_2 = outAIS.getTable(SCHEMA, TABLE);
        assertNull("Deserialized should not have declared PK", t1_2.getPrimaryKey());
        assertNotNull("Deserialized should have internal PK", t1_2.getPrimaryKeyIncludingInternal());

        compareAndAssert(inAIS, outAIS, false);
    }

    @Test
    public void writeWithRestrictedSchema() {
        final String SCHEMA1 = "test1";
        final String TABLE1 = "t1";
        final String SCHEMA2 = "test2";
        final String TABLE2 = "t2";
        NewAISBuilder builder = AISBBasedBuilder.create(typesTranslator());
        builder.table(SCHEMA1, TABLE1).colInt("id", false).colString("v", 250).pk("id");
        builder.table(SCHEMA2, TABLE2).colInt("tid", false).pk("tid");
        AkibanInformationSchema inAIS = builder.ais();
        AkibanInformationSchema outAIS1 = writeAndRead(inAIS, SCHEMA1);
        assertEquals("Serialized AIS has just schema 1", "[" + SCHEMA1 + "]", outAIS1.getSchemas().keySet().toString());
        AkibanInformationSchema outAIS2 = writeAndRead(inAIS, SCHEMA2);
        assertEquals("Serialized AIS has just schema 2", "[" + SCHEMA2 + "]", outAIS2.getSchemas().keySet().toString());
    }

    @Test
    public void writeWithRestrictedSchemaNoMatch() {
        AkibanInformationSchema inAIS = CAOIBuilderFiller.createAndFillBuilder(SCHEMA).ais();
        AkibanInformationSchema outAIS = writeAndRead(inAIS, SCHEMA + "foobar");
        assertEquals("Serialized AIS has no schemas", "[]", outAIS.getSchemas().keySet().toString());
    }

    @Test
    public void loadMultipleBuffers() {
        final int COUNT = 3;
        NewAISBuilder builder = AISBBasedBuilder.create(typesTranslator());
        builder.table(SCHEMA+0, "t0").colInt("id", false).pk("id");
        builder.table(SCHEMA+1, "t1").colBigInt("bid", false).colString("v", 32).pk("bid");
        builder.table(SCHEMA+2, "t2").colDouble("d").colInt("l").key("d_idx", "d");
        AkibanInformationSchema inAIS = builder.ais();


        ByteBuffer bbs[] = new ByteBuffer[COUNT];
        for(int i = 0; i < COUNT; ++i) {
            bbs[i] = createByteBuffer();
            ProtobufWriter writer = new ProtobufWriter(new ProtobufWriter.SingleSchemaSelector(SCHEMA+i));
            writer.save(inAIS);
            writer.serialize(bbs[i]);
        }

        AkibanInformationSchema outAIS = new AkibanInformationSchema();
        ProtobufReader reader = new ProtobufReader(typesRegistry(), storageFormatRegistry(), outAIS);
        for(int i = 0; i < COUNT; ++i) {
            bbs[i].flip();
            reader.loadBuffer(bbs[i]);
        }
        reader.loadAIS();

        compareAndAssert(inAIS, outAIS, true);
    }

    @Test
    public void groupAndIndexTreeNames() {
        final String GROUP_TREENAME = "foo";
        final String PARENT_PK_TREENAME = "bar";
        final String GROUP_INDEX_TREENAME = "zap";
        NewAISBuilder builder = AISBBasedBuilder.create(SCHEMA, typesTranslator());
        builder.table("parent").colInt("pid", false).colString("v", 32).pk("pid").key("v", "v");
        builder.table("child").colInt("cid", false).colInt("pid").pk("pid").joinTo("parent").on("pid", "pid");
        builder.groupIndex("v_cid", Index.JoinType.LEFT).on("parent", "v").and("child", "cid");

        AkibanInformationSchema inAIS = builder.ais();
        Table inParent = inAIS.getTable(SCHEMA, "parent");
        inParent.getGroup().setStorageDescription(new TestStorageDescription(inParent.getGroup(), GROUP_TREENAME, identifier));
        inParent.getGroup().getIndex("v_cid").setStorageDescription(new TestStorageDescription(inParent.getGroup().getIndex("v_cid"), GROUP_INDEX_TREENAME, identifier));
        inParent.getIndex("PRIMARY").setStorageDescription(new TestStorageDescription(inParent.getIndex("PRIMARY"), PARENT_PK_TREENAME, identifier));

        AkibanInformationSchema outAIS = writeAndRead(inAIS);
        compareAndAssert(inAIS, outAIS, true);

        Table outParent = outAIS.getTable(SCHEMA, "parent");
        assertEquals("group treename", GROUP_TREENAME, outParent.getGroup().getStorageUniqueKey());
        assertEquals("parent pk treename", PARENT_PK_TREENAME, inParent.getIndex("PRIMARY").getStorageUniqueKey());
        assertEquals("group index treename", GROUP_INDEX_TREENAME, inParent.getGroup().getIndex("v_cid").getStorageUniqueKey());
    }

    @Test
    public void tableVersionNumber() {
        final String TABLE = "t1";
        NewAISBuilder builder = AISBBasedBuilder.create(SCHEMA, typesTranslator());
        builder.table(TABLE).colInt("pid", false).pk("pid");

        AkibanInformationSchema inAIS = builder.ais();
        AkibanInformationSchema outAIS = writeAndRead(inAIS);
        assertSame("Table without version", null, outAIS.getTable(SCHEMA, TABLE).getVersion());

        final Integer VERSION = 5;
        inAIS.getTable(SCHEMA, TABLE).setVersion(VERSION);
        outAIS = writeAndRead(inAIS);
        assertEquals("Table with version", VERSION, outAIS.getTable(SCHEMA, TABLE).getVersion());
    }

    @Test
    public void sameRootTableNameTwoSchemas() {
        NewAISBuilder builder = AISBBasedBuilder.create(typesTranslator());
        builder.table(SCHEMA+"1", "t").colInt("id", false).pk("id");
        builder.table(SCHEMA+"2", "t").colInt("id", false).pk("id");
        AkibanInformationSchema inAIS = builder.ais();
        writeAndRead(inAIS);
    }
   
    @Test
    public void sequenceSimple () {
        TableName seqName = new TableName (SCHEMA, "Sequence-1");
        NewAISBuilder builder = AISBBasedBuilder.create(typesTranslator());
        builder.defaultSchema(SCHEMA);
        builder.sequence(seqName.getTableName());
        AkibanInformationSchema inAIS = builder.ais();
        AkibanInformationSchema outAIS = writeAndRead(inAIS);
        assertNotNull(outAIS.getSequence(new TableName(SCHEMA, "Sequence-1")));
        Sequence sequence = outAIS.getSequence(new TableName(SCHEMA, "Sequence-1"));
        assertEquals(1, sequence.getStartsWith());
        assertEquals(1, sequence.getIncrement());
        assertEquals(Long.MIN_VALUE, sequence.getMinValue());
        assertEquals(Long.MAX_VALUE, sequence.getMaxValue());
        assertTrue(!sequence.isCycle());
    }
   
    @Test
    public void sequenceComplex() {
        NewAISBuilder builder = AISBBasedBuilder.create(typesTranslator());
        builder.defaultSchema(SCHEMA);
        builder.sequence("sequence-2", 42, -2, true);
        AkibanInformationSchema inAIS = builder.ais();
        AkibanInformationSchema outAIS = writeAndRead(inAIS);
        assertNotNull(outAIS.getSequence(new TableName(SCHEMA, "sequence-2")));
        Sequence sequence = outAIS.getSequence(new TableName(SCHEMA, "sequence-2"));
        assertEquals(42, sequence.getStartsWith());
        assertEquals(-2, sequence.getIncrement());
        assertTrue(sequence.isCycle());
    }
   
    @Test
    public void sequenceTree() {
        NewAISBuilder builder = AISBBasedBuilder.create(typesTranslator());
        TableName seqName = new TableName (SCHEMA, "sequence-3");
        builder.defaultSchema(SCHEMA);
        builder.sequence("sequence-3", 42, -2, true);
        AkibanInformationSchema inAIS = builder.ais();
        Sequence inSeq = inAIS.getSequence(seqName);
        inSeq.setStorageDescription(new TestStorageDescription(inSeq, "sequence-3.tree", identifier));
       
        AkibanInformationSchema outAIS = writeAndRead(inAIS);
        assertNotNull(outAIS.getSequence(seqName));
        Sequence sequence = outAIS.getSequence(seqName);
        assertEquals ("sequence-3.tree", sequence.getStorageUniqueKey());
    }
   
    @Test
    public void columnSequence() {
        NewAISBuilder builder = AISBBasedBuilder.create(SCHEMA, typesTranslator());
        TableName sequenceName = new TableName (SCHEMA, "sequence-4");
        builder.sequence(sequenceName.getTableName());
        builder.table("customers").
            colBigInt("customer_id", false).
            colString("customer_name", 100, false).
            pk("customer_id");
        AkibanInformationSchema inAIS = builder.unvalidatedAIS();
        Column idColumn = inAIS.getTable(new TableName (SCHEMA, "customers")).getColumn(0);
        idColumn.setDefaultIdentity(true);
        idColumn.setIdentityGenerator(inAIS.getSequence(sequenceName));
       
        AkibanInformationSchema outAIS = writeAndRead(builder.ais());
       
        assertNotNull(outAIS.getSequence(sequenceName));
        Column outColumn = outAIS.getTable(new TableName(SCHEMA, "customers")).getColumn(0);
        assertNotNull (outColumn.getDefaultIdentity());
        assertTrue (outColumn.getDefaultIdentity());
        assertNotNull (outColumn.getIdentityGenerator());
        assertSame (outColumn.getIdentityGenerator(), outAIS.getSequence(sequenceName));
    }

    @Test
    public void indexColumnIndexedLength() {
        final String TABLE = "t";
        final Integer INDEXED_LENGTH = 16;
        AISBuilder builder = new AISBuilder();
        builder.table(SCHEMA, TABLE);
        builder.column(SCHEMA, TABLE, "v", 0, typesRegistry().getTypeClass("MCOMPAT", "VARCHAR").instance(32, false), false, null, null);
        builder.index(SCHEMA, TABLE, "v");
        builder.indexColumn(SCHEMA, TABLE, "v", "v", 0, true, INDEXED_LENGTH);
        builder.createGroup(TABLE, SCHEMA);
        builder.addTableToGroup(TABLE, SCHEMA, TABLE);
        builder.basicSchemaIsComplete();
        builder.groupingIsComplete();

        AkibanInformationSchema outAIS = writeAndRead(builder.akibanInformationSchema());
        Table table = outAIS.getTable(SCHEMA, TABLE);
        assertNotNull("found table", table);
        assertNotNull("has v index", table.getIndex("v"));
        assertEquals("v indexed length", INDEXED_LENGTH, table.getIndex("v").getKeyColumns().get(0).getIndexedLength());
    }

    @Test
    public void maxStorageSizeAndPrefixSize() {
        final String TABLE = "t";
        NewAISBuilder builder = AISBBasedBuilder.create(SCHEMA, typesTranslator());
        builder.table(TABLE).colBigInt("id");
        AkibanInformationSchema inAIS = builder.unvalidatedAIS();

        // Note: If storage* methods go away, or are non-null by default, that is *good* and these can go away
        Column inCol = inAIS.getTable(SCHEMA, TABLE).getColumn(0);
        assertNull("storedMaxStorageSize null by default", inCol.getMaxStorageSizeWithoutComputing());
        assertNull("storedPrefixSize null by default", inCol.getPrefixSizeWithoutComputing());

        AkibanInformationSchema outAIS = writeAndRead(inAIS);
        Column outCol = outAIS.getTable(SCHEMA, TABLE).getColumn(0);
        assertNull("storedMaxStorageSize null preserved", outCol.getMaxStorageSizeWithoutComputing());
        assertNull("storedPrefixSize null preserved", outCol.getPrefixSizeWithoutComputing());

        inCol.getMaxStorageSize();
        inCol.getPrefixSize();

        outAIS = writeAndRead(inAIS);
        outCol = outAIS.getTable(SCHEMA, TABLE).getColumn(0);
        assertEquals("storedMaxStorageSize", Long.valueOf(8L), outCol.getMaxStorageSizeWithoutComputing());
        assertEquals("storedPrefixSize", Integer.valueOf(0), outCol.getPrefixSizeWithoutComputing());
    }

    @Test
    public void columnDefaultValue() {
        final String TABLE = "t";
        NewAISBuilder builder = AISBBasedBuilder.create(SCHEMA, typesTranslator());
        builder.table(TABLE).colBigInt("id");

        AkibanInformationSchema inAIS = builder.unvalidatedAIS();
        Column inCol = inAIS.getTable(SCHEMA, TABLE).getColumn("id");

        AkibanInformationSchema outAIS = writeAndRead(inAIS);
        Column outCol = outAIS.getTable(SCHEMA, TABLE).getColumn("id");
        assertEquals("default defaultValue null", inCol.getDefaultValue(), outCol.getDefaultValue());

        inCol.setDefaultValue("100");
        outAIS = writeAndRead(inAIS);
        outCol = outAIS.getTable(SCHEMA, TABLE).getColumn("id");
        assertEquals("defaultValue", inCol.getDefaultValue(), outCol.getDefaultValue());
    }

    @Test
    public void procedureJava() {
        NewAISBuilder builder = AISBBasedBuilder.create(SCHEMA, typesTranslator());
        builder.sqljJar("myjar")
            // A file URL would vary by testing system. But don't check exists.
            .url("http://example.com/procs.jar", false);
        builder.procedure("PROC1")
            .language("java", Routine.CallingConvention.JAVA)
            .paramLongIn("x1")
            .paramLongIn("x2")
            .paramDoubleOut("d")
            .externalName("myjar", "com.acme.Procs", "proc1")
            .sqlAllowed(Routine.SQLAllowed.READS_SQL_DATA)
            .dynamicResultSets(2);
       
        AkibanInformationSchema inAIS = builder.ais();
        AkibanInformationSchema outAIS = writeAndRead(inAIS);

        Routine proc = outAIS.getRoutine(SCHEMA, "PROC1");
        assertNotNull(proc);
       
        SQLJJar jar = proc.getSQLJJar();
        assertNotNull(jar);
        assertEquals("myjar", jar.getName().getTableName());
        assertEquals("http://example.com/procs.jar", jar.getURL().toString());

        assertEquals("java", proc.getLanguage());
        assertEquals(Routine.CallingConvention.JAVA, proc.getCallingConvention());
        assertEquals(3, proc.getParameters().size());
        assertEquals("x1", proc.getParameters().get(0).getName());
        assertEquals(Parameter.Direction.IN, proc.getParameters().get(0).getDirection());
        assertEquals("BIGINT", proc.getParameters().get(0).getTypeName());
        assertEquals("x2", proc.getParameters().get(1).getName());
        assertEquals("BIGINT", proc.getParameters().get(1).getTypeName());
        assertEquals(Parameter.Direction.IN, proc.getParameters().get(1).getDirection());
        assertEquals("d", proc.getParameters().get(2).getName());
        assertEquals("DOUBLE", proc.getParameters().get(2).getTypeName());
        assertEquals(Parameter.Direction.OUT, proc.getParameters().get(2).getDirection());
        assertEquals("com.acme.Procs", proc.getClassName());
        assertEquals("proc1", proc.getMethodName());
        assertEquals(Routine.SQLAllowed.READS_SQL_DATA, proc.getSQLAllowed());
        assertEquals(2, proc.getDynamicResultSets());
    }

    @Test
    public void procedureLoadablePlan() {
        NewAISBuilder builder = AISBBasedBuilder.create(SCHEMA, typesTranslator());
        builder.procedure("PROC2")
            .language("java", Routine.CallingConvention.LOADABLE_PLAN)
            .externalName("com.acme.Procs", "proc1");
       
        AkibanInformationSchema inAIS = builder.ais();
        AkibanInformationSchema outAIS = writeAndRead(inAIS);

        Routine proc = outAIS.getRoutine(SCHEMA, "PROC2");
       
        assertEquals("java", proc.getLanguage());
        assertEquals(Routine.CallingConvention.LOADABLE_PLAN, proc.getCallingConvention());
        assertEquals(0, proc.getParameters().size());
    }

    private AkibanInformationSchema writeAndRead(AkibanInformationSchema inAIS) {
        return writeAndRead(inAIS, null);
    }

    private AkibanInformationSchema writeAndRead(AkibanInformationSchema inAIS, String restrictSchema) {
        ByteBuffer bb = createByteBuffer();

        final ProtobufWriter writer;
        if(restrictSchema == null) {
            writer = new ProtobufWriter();
        } else {
            writer = new ProtobufWriter(new ProtobufWriter.SingleSchemaSelector(restrictSchema));
        }
        writer.save(inAIS);
        writer.serialize(bb);

        bb.flip();
        ProtobufReader reader = new ProtobufReader(typesRegistry(), storageFormatRegistry()).loadBuffer(bb);
        return reader.loadAIS().getAIS();
    }

    private ByteBuffer createByteBuffer() {
        return ByteBuffer.allocate(4096);
    }

    private static TypesRegistry typesRegistry() {
        return TestTypesRegistry.MCOMPAT;
    }

    private static TypesTranslator typesTranslator() {
        return MTypesTranslator.INSTANCE;
    }

    private static StorageFormatRegistry storageFormatRegistry() {
        return DummyStorageFormatRegistry.create();
    }
}
TOP

Related Classes of com.foundationdb.ais.protobuf.ProtobufReaderWriterTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.