/**
* 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.server.store.format.protobuf;
import com.foundationdb.ais.model.AkibanInformationSchema;
import com.foundationdb.ais.model.Column;
import com.foundationdb.ais.model.Group;
import com.foundationdb.ais.model.Table;
import com.foundationdb.ais.model.TableName;
import com.foundationdb.ais.protobuf.CommonProtobuf.ProtobufRowFormat;
import com.foundationdb.protobuf.ProtobufDecompiler;
import com.foundationdb.server.rowdata.RowData;
import com.foundationdb.server.rowdata.RowDef;
import com.foundationdb.server.rowdata.SchemaFactory;
import com.google.protobuf.DescriptorProtos.FileDescriptorSet;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.DynamicMessage;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import java.math.BigDecimal;
import java.util.UUID;
public class ProtobufRowDataConverterTest
{
private static final String SCHEMA = "test";
protected AkibanInformationSchema ais(String ddl) {
AkibanInformationSchema ais = new SchemaFactory(SCHEMA).aisWithRowDefs(ddl);
for (Table table : ais.getTables().values()) {
if (!table.hasVersion()) {
table.setVersion(0);
}
if (table.getUuid() == null)
table.setUuid(UUID.randomUUID());
for (Column column : table.getColumnsIncludingInternal()) {
if (column.getUuid() == null)
column.setUuid(UUID.randomUUID());
}
}
return ais;
}
protected ProtobufRowDataConverter converter(Group g) throws Exception {
AISToProtobuf a2p = new AISToProtobuf(ProtobufRowFormat.Type.GROUP_MESSAGE);
a2p.addGroup(g);
FileDescriptorSet set = a2p.build();
if (false) {
new ProtobufDecompiler((Appendable)System.out).decompile(set);
}
FileDescriptor gdesc = FileDescriptor.buildFrom(set.getFile(0),
ProtobufStorageDescriptionHelper.DEPENDENCIES);
return ProtobufRowDataConverter.forGroup(g, gdesc);
}
protected void encodeDecode(AkibanInformationSchema ais,
ProtobufRowDataConverter converter,
RowDef rowDef,
Object... values)
throws Exception {
RowData rowDataIn = new RowData(new byte[128]);
rowDataIn.createRow(rowDef, values, true);
DynamicMessage msg = converter.encode(rowDataIn);
if (false) {
System.out.println(converter.shortFormat(msg));
}
RowData rowDataOut = new RowData(new byte[128]);
converter.decode(msg, rowDataOut);
assertEquals("rows match", rowDataIn.toString(ais), rowDataOut.toString(ais));
}
@Test
public void testSimple() throws Exception {
AkibanInformationSchema ais = ais(
"CREATE TABLE t(id INT PRIMARY KEY NOT NULL, s VARCHAR(128), d DOUBLE)");
Group g = ais.getGroup(new TableName(SCHEMA, "t"));
RowDef tRowDef = g.getRoot().rowDef();
ProtobufRowDataConverter converter = converter(g);
encodeDecode(ais, converter, tRowDef,
1L, "Fred", 3.14);
}
@Test
public void testGroup() throws Exception {
AkibanInformationSchema ais = ais(
"CREATE TABLE c(cid INT PRIMARY KEY NOT NULL, name VARCHAR(128));" +
"CREATE TABLE o(oid INT PRIMARY KEY NOT NULL, cid INT, GROUPING FOREIGN KEY(cid) REFERENCES c(cid));" +
"CREATE TABLE i(iid INT PRIMARY KEY NOT NULL, oid INT, GROUPING FOREIGN KEY(oid) REFERENCES o(oid), sku VARCHAR(16));");
Group coi = ais.getGroup(new TableName(SCHEMA, "c"));
RowDef cRowDef = ais.getTable(new TableName(SCHEMA, "c")).rowDef();
RowDef oRowDef = ais.getTable(new TableName(SCHEMA, "o")).rowDef();
RowDef iRowDef = ais.getTable(new TableName(SCHEMA, "i")).rowDef();
ProtobufRowDataConverter converter = converter(coi);
encodeDecode(ais, converter, cRowDef,
1L, "Fred");
encodeDecode(ais, converter, oRowDef,
101L, 1L);
encodeDecode(ais, converter, iRowDef,
10101L, 101L, "P100");
}
@Test
public void testDecimal() throws Exception {
AkibanInformationSchema ais = ais(
"CREATE TABLE t(id INT PRIMARY KEY NOT NULL, n1 DECIMAL(6,2), n2 DECIMAL(20,10))");
Group g = ais.getGroup(new TableName(SCHEMA, "t"));
RowDef tRowDef = g.getRoot().rowDef();
ProtobufRowDataConverter converter = converter(g);
encodeDecode(ais, converter, tRowDef,
1L, new BigDecimal("3.14"), new BigDecimal("1234567890.0987654321"));
}
@Test
public void testNulls() throws Exception {
AkibanInformationSchema ais = ais(
"CREATE TABLE t(id INT PRIMARY KEY NOT NULL, s VARCHAR(128) DEFAULT 'abc')");
Group g = ais.getGroup(new TableName(SCHEMA, "t"));
RowDef tRowDef = g.getRoot().rowDef();
ProtobufRowDataConverter converter = converter(g);
encodeDecode(ais, converter, tRowDef,
1L, "Barney");
encodeDecode(ais, converter, tRowDef,
2L, null);
}
}