blob: 26db2d5c1dd190cd19357c7bb90597c70f5e14e5 [file] [log] [blame]
/*
* 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.ignite.internal.table;
import org.apache.ignite.internal.schema.Column;
import org.apache.ignite.internal.schema.InvalidTypeException;
import org.apache.ignite.internal.schema.NativeTypes;
import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.schema.SchemaMismatchException;
import org.apache.ignite.internal.table.impl.DummyInternalTableImpl;
import org.apache.ignite.internal.table.impl.DummySchemaManagerImpl;
import org.apache.ignite.internal.table.impl.TestTupleBuilder;
import org.apache.ignite.table.Table;
import org.apache.ignite.table.Tuple;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Basic table operations test.
* <p>
* TODO: IGNITE-14486 Add tests for invoke operations.
* TODO: IGNITE-14486 Add tests for bulk operations.
* TODO: IGNITE-14486 Add tests for async operations.
*/
public class TableBinaryViewOperationsTest {
/**
*
*/
@Test
public void insert() {
SchemaDescriptor schema = new SchemaDescriptor(
1,
new Column[] {new Column("id", NativeTypes.INT64, false)},
new Column[] {new Column("val", NativeTypes.INT64, false)}
);
Table tbl = new TableImpl(new DummyInternalTableImpl(), new DummySchemaManagerImpl(schema), null, null);
final Tuple tuple = Tuple.create().set("id", 1L).set("val", 11L);
final Tuple newTuple = Tuple.create().set("id", 1L).set("val", 22L);
final Tuple nonExistedTuple = Tuple.create().set("id", 2L);
assertNull(tbl.get(Tuple.create().set("id", 1L)));
// Insert new tuple.
assertTrue(tbl.insert(tuple));
assertEqualsRows(schema, tuple, tbl.get(Tuple.create().set("id", 1L)));
// Ignore insert operation for exited row.
assertFalse(tbl.insert(newTuple));
assertEqualsRows(schema, tuple, tbl.get(Tuple.create().set("id", 1L)));
assertNull(tbl.get(nonExistedTuple));
}
/**
*
*/
@Test
public void upsert() {
SchemaDescriptor schema = new SchemaDescriptor(
1,
new Column[] {new Column("id", NativeTypes.INT64, false)},
new Column[] {new Column("val", NativeTypes.INT64, false)}
);
Table tbl = new TableImpl(new DummyInternalTableImpl(), new DummySchemaManagerImpl(schema), null, null);
final Tuple tuple = Tuple.create().set("id", 1L).set("val", 11L);
final Tuple newTuple = Tuple.create().set("id", 1L).set("val", 22L);
final Tuple nonExistedTuple = Tuple.create().set("id", 2L);
assertNull(tbl.get(Tuple.create().set("id", 1L)));
// Insert new tuple.
tbl.upsert(tuple);
assertEqualsRows(schema, tuple, tbl.get(Tuple.create().set("id", 1L)));
// Update exited row.
tbl.upsert(newTuple);
assertEqualsRows(schema, newTuple, tbl.get(Tuple.create().set("id", 1L)));
assertNull(tbl.get(nonExistedTuple));
}
/**
*
*/
@Test
public void getAndUpsert() {
SchemaDescriptor schema = new SchemaDescriptor(
1,
new Column[] {new Column("id", NativeTypes.INT64, false)},
new Column[] {new Column("val", NativeTypes.INT64, false)}
);
Table tbl = new TableImpl(new DummyInternalTableImpl(), new DummySchemaManagerImpl(schema), null, null);
final Tuple tuple = Tuple.create().set("id", 1L).set("val", 11L);
final Tuple newTuple = Tuple.create().set("id", 1L).set("val", 22L);
assertNull(tbl.get(Tuple.create().set("id", 1L)));
// Insert new tuple.
assertNull(tbl.getAndUpsert(tuple));
assertEqualsRows(schema, tuple, tbl.get(Tuple.create().set("id", 1L)));
// Update exited row.
assertEqualsRows(schema, tuple, tbl.getAndUpsert(newTuple));
assertEqualsRows(schema, newTuple, tbl.get(Tuple.create().set("id", 1L)));
}
/**
*
*/
@Test
public void remove() {
SchemaDescriptor schema = new SchemaDescriptor(
1,
new Column[] {new Column("id", NativeTypes.INT64, false)},
new Column[] {new Column("val", NativeTypes.INT64, false)}
);
Table tbl = new TableImpl(new DummyInternalTableImpl(), new DummySchemaManagerImpl(schema), null, null);
tbl.upsert(Tuple.create().set("id", 1L).set("val", 11L));
final Tuple keyTuple = Tuple.create().set("id", 1L);
// Delete not existed keyTuple.
assertFalse(tbl.delete(Tuple.create().set("id", 2L)));
// Delete existed keyTuple.
assertTrue(tbl.delete(keyTuple));
assertNull(tbl.get(keyTuple));
// Delete already deleted keyTuple.
assertFalse(tbl.delete(keyTuple));
}
/**
*
*/
@Test
public void removeExact() {
SchemaDescriptor schema = new SchemaDescriptor(
1,
new Column[] {new Column("id", NativeTypes.INT64, false)},
new Column[] {new Column("val", NativeTypes.INT64, false)}
);
Table tbl = new TableImpl(new DummyInternalTableImpl(), new DummySchemaManagerImpl(schema), null, null);
final Tuple keyTuple = Tuple.create().set("id", 1L);
final Tuple tuple = Tuple.create().set("id", 1L).set("val", 11L);
final Tuple tuple2 = Tuple.create().set("id", 1L).set("val", 22L);
final Tuple nonExistedTuple = Tuple.create().set("id", 2L).set("val", 22L);
tbl.insert(tuple);
assertEqualsRows(schema, tuple, tbl.get(keyTuple));
// Fails to delete not existed tuple.
assertFalse(tbl.deleteExact(nonExistedTuple));
assertEqualsRows(schema, tuple, tbl.get(keyTuple));
// Fails to delete tuple with unexpected value.
assertFalse(tbl.deleteExact(tuple2));
assertEqualsRows(schema, tuple, tbl.get(keyTuple));
// TODO: IGNITE-14479: Fix default value usage.
// assertFalse(tbl.deleteExact(keyTuple));
// assertEqualsRows(schema, tuple, tbl.get(keyTuple));
// Delete tuple with expected value.
assertTrue(tbl.deleteExact(tuple));
assertNull(tbl.get(keyTuple));
// Once again.
assertFalse(tbl.deleteExact(tuple));
assertNull(tbl.get(keyTuple));
// Insert new.
tbl.insert(tuple2);
assertEqualsRows(schema, tuple2, tbl.get(keyTuple));
// Delete tuple with expected value.
assertTrue(tbl.deleteExact(tuple2));
assertNull(tbl.get(keyTuple));
}
/**
*
*/
@Test
public void replace() {
SchemaDescriptor schema = new SchemaDescriptor(
1,
new Column[] {new Column("id", NativeTypes.INT64, false)},
new Column[] {new Column("val", NativeTypes.INT64, false)}
);
Table tbl = new TableImpl(new DummyInternalTableImpl(), new DummySchemaManagerImpl(schema), null, null);
final Tuple keyTuple = Tuple.create().set("id", 1L);
final Tuple tuple = Tuple.create().set("id", 1L).set("val", 11L);
final Tuple tuple2 = Tuple.create().set("id", 1L).set("val", 22L);
assertNull(tbl.get(keyTuple));
// Ignore replace operation for non-existed row.
assertFalse(tbl.replace(tuple));
assertNull(tbl.get(keyTuple));
// Insert row.
tbl.insert(tuple);
// Replace existed row.
assertTrue(tbl.replace(tuple2));
assertEqualsRows(schema, tuple2, tbl.get(keyTuple));
}
/**
*
*/
@Test
public void replaceExact() {
SchemaDescriptor schema = new SchemaDescriptor(
1,
new Column[] {new Column("id", NativeTypes.INT64, false)},
new Column[] {new Column("val", NativeTypes.INT64, false)}
);
Table tbl = new TableImpl(new DummyInternalTableImpl(), new DummySchemaManagerImpl(schema), null, null);
final Tuple tuple = Tuple.create().set("id", 1L).set("val", 11L);
final Tuple tuple2 = Tuple.create().set("id", 1L).set("val", 22L);
assertNull(tbl.get(Tuple.create().set("id", 1L)));
// Ignore replace operation for non-existed row.
// TODO: IGNITE-14479: Fix default value usage.
// assertTrue(tbl.replace(keyTuple, tuple));
// assertNull(tbl.get(keyTuple));
// assertNull(tbl.get(tbl.tupleBuilder().set("id", 1L).set("val", -1)));
// Insert row.
tbl.insert(tuple);
// Replace existed row.
assertTrue(tbl.replace(tuple, tuple2));
assertEqualsRows(schema, tuple2, tbl.get(Tuple.create().set("id", 1L)));
}
/**
*
*/
@Test
public void validateSchema() {
SchemaDescriptor schema = new SchemaDescriptor(
1,
new Column[] {new Column("id", NativeTypes.INT64, false)},
new Column[] {
new Column("val", NativeTypes.INT64, true),
new Column("str", NativeTypes.stringOf(3), true),
new Column("blob", NativeTypes.blobOf(3), true)
}
);
Table tbl = new TableImpl(new DummyInternalTableImpl(), new DummySchemaManagerImpl(schema), null, null);
final Tuple keyTuple0 = new TestTupleBuilder().set("id", 0).set("id1", 0);
final Tuple keyTuple1 = new TestTupleBuilder().set("id1", 0);
final Tuple tuple0 = new TestTupleBuilder().set("id", 1L).set("str", "qweqweqwe").set("val", 11L);
final Tuple tuple1 = new TestTupleBuilder().set("id", 1L).set("blob", new byte[] {0, 1, 2, 3}).set("val", 22L);
assertThrows(InvalidTypeException.class, () -> tbl.get(keyTuple0));
assertThrows(SchemaMismatchException.class, () -> tbl.get(keyTuple1));
assertThrows(InvalidTypeException.class, () -> tbl.replace(tuple0));
assertThrows(InvalidTypeException.class, () -> tbl.replace(tuple1));
assertThrows(InvalidTypeException.class, () -> tbl.insert(tuple0));
assertThrows(InvalidTypeException.class, () -> tbl.insert(tuple1));
assertThrows(InvalidTypeException.class, () -> tbl.replace(tuple0));
assertThrows(InvalidTypeException.class, () -> tbl.replace(tuple1));
}
/**
*
*/
@Test
public void defaultValues() {
SchemaDescriptor schema = new SchemaDescriptor(
1,
new Column[] {new Column("id", NativeTypes.INT64, false)},
new Column[] {
new Column("val", NativeTypes.INT64, true, () -> 28L),
new Column("str", NativeTypes.stringOf(3), true, () -> "ABC"),
new Column("blob", NativeTypes.blobOf(3), true, () -> new byte[] {0, 1, 2})
}
);
Table tbl = new TableImpl(new DummyInternalTableImpl(), new DummySchemaManagerImpl(schema), null, null);
final Tuple keyTuple0 = Tuple.create().set("id", 0L);
final Tuple keyTuple1 = Tuple.create().set("id", 1L);
final Tuple tuple0 = Tuple.create().set("id", 0L);
final Tuple tupleExpected0 = Tuple.create().set("id", 0L).set("val", 28L).set("str", "ABC").set("blob", new byte[] {0, 1, 2});
final Tuple tuple1 = Tuple.create().set("id", 1L).set("val", null).set("str", null).set("blob", null);
tbl.insert(tuple0);
tbl.insert(tuple1);
assertEqualsRows(schema, tupleExpected0, tbl.get(keyTuple0));
assertEqualsRows(schema, tuple1, tbl.get(keyTuple1));
}
/**
* Check tuples equality.
*
* @param schema Schema.
* @param expected Expected tuple.
* @param actual Actual tuple.
*/
void assertEqualsRows(SchemaDescriptor schema, Tuple expected, Tuple actual) {
assertEqualsKeys(schema, expected, actual);
assertEqualsValues(schema, expected, actual);
}
/**
* Check key columns equality.
*
* @param schema Schema.
* @param expected Expected tuple.
* @param actual Actual tuple.
*/
void assertEqualsKeys(SchemaDescriptor schema, Tuple expected, Tuple actual) {
int nonNullKey = 0;
for (int i = 0; i < schema.keyColumns().length(); i++) {
final Column col = schema.keyColumns().column(i);
final Object val1 = expected.value(col.name());
final Object val2 = actual.value(col.name());
Assertions.assertEquals(val1, val2, "Value columns equality check failed: colIdx=" + col.schemaIndex());
if (schema.isKeyColumn(i) && val1 != null)
nonNullKey++;
}
assertTrue(nonNullKey > 0, "At least one non-null key column must exist.");
}
/**
* Check value columns equality.
*
* @param schema Schema.
* @param expected Expected tuple.
* @param actual Actual tuple.
*/
void assertEqualsValues(SchemaDescriptor schema, Tuple expected, Tuple actual) {
for (int i = 0; i < schema.valueColumns().length(); i++) {
final Column col = schema.valueColumns().column(i);
final Object val1 = expected.value(col.name());
final Object val2 = actual.value(col.name());
if (val1 instanceof byte[] && val2 instanceof byte[])
Assertions.assertArrayEquals((byte[])val1, (byte[])val2, "Equality check failed: colIdx=" + col.schemaIndex());
else
Assertions.assertEquals(val1, val2, "Equality check failed: colIdx=" + col.schemaIndex());
}
}
}