You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2021/01/22 10:56:51 UTC

[ignite-3] branch ignite-14035 created (now 528cfde)

This is an automated email from the ASF dual-hosted git repository.

amashenkov pushed a change to branch ignite-14035
in repository https://gitbox.apache.org/repos/asf/ignite-3.git.


      at 528cfde  Table access API. Draft. Simple examples added.

This branch includes the following new commits:

     new 528cfde  Table access API. Draft. Simple examples added.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[ignite-3] 01/01: Table access API. Draft. Simple examples added.

Posted by am...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

amashenkov pushed a commit to branch ignite-14035
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit 528cfdec2de83ea3b87cd3ef03234aa78b05bec9
Author: Andrew Mashenkov <an...@gmail.com>
AuthorDate: Fri Jan 22 13:01:57 2021 +0300

    Table access API. Draft.
    Simple examples added.
---
 modules/commons/pom.xml                            |  58 ++++
 .../java/org/apache/ignite/storage/KVView.java     |  29 ++
 .../main/java/org/apache/ignite/storage/Row.java   |  31 ++
 .../main/java/org/apache/ignite/storage/Table.java |  46 +++
 .../java/org/apache/ignite/storage/TableView.java  |  29 ++
 .../apache/ignite/storage/binary/BinaryObject.java |  25 ++
 .../ignite/storage/binary/BinaryObjects.java       |  27 ++
 .../apache/ignite/storage/mapper/KeyMapper.java    |  24 ++
 .../org/apache/ignite/storage/mapper/Mappers.java  |  43 +++
 .../apache/ignite/storage/mapper/RowMapper.java    |  32 ++
 .../apache/ignite/storage/mapper/ValueMapper.java  |  33 ++
 .../java/org/apache/ignite/storage/Example.java    | 335 +++++++++++++++++++++
 pom.xml                                            |   3 +-
 13 files changed, 714 insertions(+), 1 deletion(-)

diff --git a/modules/commons/pom.xml b/modules/commons/pom.xml
new file mode 100644
index 0000000..5ea7ce9
--- /dev/null
+++ b/modules/commons/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<!--
+    POM file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>apache-ignite</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>ignite-commons</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jetbrains</groupId>
+            <artifactId>annotations</artifactId>
+            <version>${jetbrains.annotations.version}</version>
+        </dependency>
+
+        <!-- Test dependencies -->
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>${junit.jupiter.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <version>${junit.jupiter.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/modules/commons/src/main/java/org/apache/ignite/storage/KVView.java b/modules/commons/src/main/java/org/apache/ignite/storage/KVView.java
new file mode 100644
index 0000000..f093f75
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/storage/KVView.java
@@ -0,0 +1,29 @@
+/*
+ * 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.storage;
+
+/**
+ *
+ */
+public interface KVView<K, V> {
+    public V get(K key);
+
+    public V put(K key, V val);
+
+    public boolean putIfAbsent(K key, V val);
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/storage/Row.java b/modules/commons/src/main/java/org/apache/ignite/storage/Row.java
new file mode 100644
index 0000000..06f5800
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/storage/Row.java
@@ -0,0 +1,31 @@
+/*
+ * 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.storage;
+
+import org.apache.ignite.storage.binary.BinaryObject;
+
+/**
+ *
+ */
+public interface Row {
+    public <T> T field(String name);
+
+    public BinaryObject binaryObjectField(String fieldName);
+
+    int intField(String fieldName);
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/storage/Table.java b/modules/commons/src/main/java/org/apache/ignite/storage/Table.java
new file mode 100644
index 0000000..2e0a36d
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/storage/Table.java
@@ -0,0 +1,46 @@
+/*
+ * 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.storage;
+
+import org.apache.ignite.storage.mapper.KeyMapper;
+import org.apache.ignite.storage.mapper.Mappers;
+import org.apache.ignite.storage.mapper.RowMapper;
+import org.apache.ignite.storage.mapper.ValueMapper;
+
+/**
+ *
+ */
+public interface Table {
+    public <R> TableView<R> tableView(RowMapper<R> rowMapper);
+
+    public <K, V> KVView<K, V> kvView(KeyMapper<K> keyMapper, ValueMapper<V> valMapper);
+
+    public default <K, V> KVView<K, V> kvView(Class<K> kCls, Class<V> vCls) {
+        return kvView(Mappers.ofKeyClass(kCls), Mappers.ofValueClass(vCls));
+    }
+
+    public Row get(Row keyRow);
+
+    public Iterable<Row> find(Row template);
+
+    public boolean upsert(Row row);
+
+    public boolean insert(Row row);
+
+    Row createSearchRow(Object... args);
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/storage/TableView.java b/modules/commons/src/main/java/org/apache/ignite/storage/TableView.java
new file mode 100644
index 0000000..4ded1e6
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/storage/TableView.java
@@ -0,0 +1,29 @@
+/*
+ * 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.storage;
+
+/**
+ *
+ */
+public interface TableView<T> {
+    public T get(T keyRow);
+
+    public boolean upsert(T row);
+
+    public boolean insert(T row);
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/storage/binary/BinaryObject.java b/modules/commons/src/main/java/org/apache/ignite/storage/binary/BinaryObject.java
new file mode 100644
index 0000000..8257bf5
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/storage/binary/BinaryObject.java
@@ -0,0 +1,25 @@
+/*
+ * 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.storage.binary;
+
+/**
+ *
+ */
+public interface BinaryObject {
+    Object deserialize(Class<?> targetCls);
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/storage/binary/BinaryObjects.java b/modules/commons/src/main/java/org/apache/ignite/storage/binary/BinaryObjects.java
new file mode 100644
index 0000000..d4d3424
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/storage/binary/BinaryObjects.java
@@ -0,0 +1,27 @@
+/*
+ * 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.storage.binary;
+
+/**
+ *
+ */
+public class BinaryObjects {
+    public static BinaryObject wrap(byte[] objData) {
+        return null;
+    }
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/storage/mapper/KeyMapper.java b/modules/commons/src/main/java/org/apache/ignite/storage/mapper/KeyMapper.java
new file mode 100644
index 0000000..588da5f
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/storage/mapper/KeyMapper.java
@@ -0,0 +1,24 @@
+/*
+ * 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.storage.mapper;
+
+/**
+ *
+ */
+public interface KeyMapper<T> {
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/storage/mapper/Mappers.java b/modules/commons/src/main/java/org/apache/ignite/storage/mapper/Mappers.java
new file mode 100644
index 0000000..60db61c
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/storage/mapper/Mappers.java
@@ -0,0 +1,43 @@
+/*
+ * 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.storage.mapper;
+
+/**
+ *
+ */
+public class Mappers {
+    public static <K> KeyMapper<K> ofKeyClass(Class<K> keyCls) {
+        return null;
+    }
+
+    public static <V> ValueMapper<V> ofValueClass(Class<V> keyCls) {
+        return null;
+    }
+
+    public static <V> ValueMapper.Builder<V> ofValueClassBuilder(Class<V> valCls) {
+        return null;
+    }
+
+    public static <R> RowMapper<R> ofRowClass(Class<R> rowCls) {
+        return null;
+    }
+
+    public static <R> RowMapper.Builder<R> ofRowClassBuilder(Class<R> targetClass) {
+        return null;
+    }
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/storage/mapper/RowMapper.java b/modules/commons/src/main/java/org/apache/ignite/storage/mapper/RowMapper.java
new file mode 100644
index 0000000..0a4bdd2
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/storage/mapper/RowMapper.java
@@ -0,0 +1,32 @@
+/*
+ * 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.storage.mapper;
+
+import java.util.function.Function;
+import org.apache.ignite.storage.Row;
+
+/**
+ *
+ */
+public interface RowMapper<R> {
+    public interface Builder<R> {
+        public Builder<R> deserializing(String fieldName, Class<?> targetClass);
+        public Builder<R> map(String fieldName, Function<Row, Object> mapping);
+        public <R> RowMapper<R> build();
+    }
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/storage/mapper/ValueMapper.java b/modules/commons/src/main/java/org/apache/ignite/storage/mapper/ValueMapper.java
new file mode 100644
index 0000000..b8e7139
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/storage/mapper/ValueMapper.java
@@ -0,0 +1,33 @@
+/*
+ * 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.storage.mapper;
+
+import java.util.function.Function;
+import org.apache.ignite.storage.Row;
+
+/**
+ *
+ */
+public interface ValueMapper<V> {
+    public interface Builder<V> {
+        public Builder<V> deserializing(String fieldName, Class<?> cls);
+        public Builder<V> map(String fieldName, Function<Row, Object> mapper);
+
+        public ValueMapper<V> build();
+    }
+}
diff --git a/modules/commons/src/test/java/org/apache/ignite/storage/Example.java b/modules/commons/src/test/java/org/apache/ignite/storage/Example.java
new file mode 100644
index 0000000..7b91c65
--- /dev/null
+++ b/modules/commons/src/test/java/org/apache/ignite/storage/Example.java
@@ -0,0 +1,335 @@
+/*
+ * 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.storage;
+
+import java.math.BigDecimal;
+import org.apache.ignite.storage.binary.BinaryObject;
+import org.apache.ignite.storage.binary.BinaryObjects;
+import org.apache.ignite.storage.mapper.Mappers;
+
+/**
+ *
+ */
+@SuppressWarnings({"unused", "UnusedAssignment"})
+public class Example {
+    /**
+     * Use case 1: a simple one. The table has the structure
+     * [
+     * [id int, orgId int] // key
+     * [name varchar, lastName varchar, decimal salary, int department] // value
+     * ]
+     * We show how to use the raw TableRow and a mapped class.
+     */
+    public void useCase1(Table t) {
+        // Search row will allow nulls even in non-null columns.
+        Row res = t.get(t.createSearchRow(1, 1));
+
+        String name = res.field("name");
+        String lastName = res.field("latName");
+        BigDecimal salary = res.field("salary");
+        Integer department = res.field("department");
+
+        // We may have primitive-returning methods if needed.
+        int departmentPrimitive = res.intField("department");
+
+        // Note that schema itself already defined which fields are key field.
+        class Employee {
+            final int id;
+            final int orgId;
+
+            String name;
+            String lastName;
+            BigDecimal salary;
+            int department;
+
+            Employee(int id, int orgId) {
+                this.id = id;
+                this.orgId = orgId;
+            }
+        }
+
+        TableView<Employee> employeeView = t.tableView(Mappers.ofRowClass(Employee.class));
+
+        Employee e = employeeView.get(new Employee(1, 1));
+
+        // As described in the IEP, we can have a truncated mapping.
+        class TruncatedEmployee {
+            final int id;
+            final int orgId;
+
+            String name;
+            String lastName;
+
+            TruncatedEmployee(int id, int orgId) {
+                this.id = id;
+                this.orgId = orgId;
+            }
+        }
+
+        TableView<TruncatedEmployee> truncatedEmployeeView = t.tableView(Mappers.ofRowClass(TruncatedEmployee.class));
+
+        // salary and department will not be sent over the network during this call.
+        TruncatedEmployee te = truncatedEmployeeView.get(new TruncatedEmployee(1, 1));
+    }
+
+    /**
+     * Use case 2: using simple KV mappings
+     * The table has structure is
+     * [
+     * [id int, orgId int] // key
+     * [name varchar, lastName varchar, decimal salary, int department] // value
+     * ]
+     */
+    public void useCase2(Table t) {
+        class EmployeeKey {
+            final int id;
+            final int orgId;
+
+            EmployeeKey(int id, int orgId) {
+                this.id = id;
+                this.orgId = orgId;
+            }
+        }
+
+        class Employee {
+            String name;
+            String lastName;
+            BigDecimal salary;
+            int department;
+        }
+
+        KVView<EmployeeKey, Employee> employeeKv = t.kvView(
+            Mappers.ofKeyClass(EmployeeKey.class),
+            Mappers.ofValueClass(Employee.class));
+
+        employeeKv.get(new EmployeeKey(1, 1));
+
+        // As described in the IEP, we can have a truncated KV mapping.
+        class TruncatedEmployee {
+            String name;
+            String lastName;
+        }
+
+        KVView<EmployeeKey, TruncatedEmployee> truncatedEmployeeKv = t.kvView(
+            Mappers.ofKeyClass(EmployeeKey.class),
+            Mappers.ofValueClass(TruncatedEmployee.class));
+
+        TruncatedEmployee te = truncatedEmployeeKv.get(new EmployeeKey(1, 1));
+    }
+
+    /**
+     * Use case 3: Single table strategy for inherited objects.
+     * The table has structure is
+     * [
+     * [id long] // key
+     * [owner varchar, cardNumber long, expYear int, expMonth int, accountNum long, bankName varchar] // value
+     * ]
+     */
+    public void useCase3(Table t) {
+        class BillingDetails {
+            String owner;
+        }
+
+        class CreditCard extends BillingDetails {
+            long cardNumber;
+            int expYear;
+            int expMonth;
+        }
+
+        class BankAccount extends BillingDetails {
+            long account;
+            String bankName;
+        }
+
+        KVView<Long, CreditCard> credCardKvView = t.kvView(
+            Mappers.ofKeyClass(Long.class),
+            Mappers.ofValueClass(CreditCard.class));
+
+        CreditCard cred = credCardKvView.get(1L);
+
+        KVView<Long, BankAccount> backAccKvView = t.kvView(
+            Mappers.ofKeyClass(Long.class),
+            Mappers.ofValueClass(BankAccount.class));
+
+        BankAccount ewd = backAccKvView.get(2L);
+    }
+
+    /**
+     * Use case 4: Conditional serialization.
+     * The table has structure is
+     * [
+     * [id int, orgId int] // key
+     * [owner varchar, type int, conditionalDetails byte[]] // value
+     * ]
+     */
+    public void useCase4(Table t) {
+        class OrderKey {
+            final int id;
+            final int orgId;
+
+            OrderKey(int id, int orgId) {
+                this.id = id;
+                this.orgId = orgId;
+            }
+        }
+
+        class OrderValue {
+            String owner;
+            int type;
+            Object billingDetails;
+        }
+
+        class CreditCard {
+            long cardNumber;
+            int expYear;
+            int expMonth;
+        }
+
+        class BankAccount {
+            long account;
+            String bankName;
+        }
+
+        KVView<OrderKey, OrderValue> orderKvView = t.kvView(Mappers.ofKeyClass(OrderKey.class),
+            Mappers.ofValueClassBuilder(OrderValue.class)
+                .map("billingDetails", (row) -> {
+                    BinaryObject bobj = row.binaryObjectField("conditionalDetails");
+                    int type = row.intField("type");
+
+                    return bobj.deserialize(type == 0 ? CreditCard.class : BankAccount.class);
+                }).build());
+
+        OrderValue ov = orderKvView.get(new OrderKey(1, 1));
+
+        // Same with RecordAPI.
+        Row res = t.get(t.createSearchRow(1, 1));
+
+        byte[] objData = res.field("billingDetails");
+        BinaryObject binObj = BinaryObjects.wrap(objData);
+        // Work with the binary object as in Ignite 2.x
+
+        // Additionally, we may have a shortcut similar to primitive methods.
+        binObj = res.binaryObjectField("billingDetails");
+
+        class OrderRecord {
+            final int id;
+            final int orgId;
+
+            String owner;
+            int type;
+            BinaryObject billingDetails;
+
+            OrderRecord(int id, int orgId) {
+                this.id = id;
+                this.orgId = orgId;
+            }
+        }
+
+        final TableView<OrderRecord> orderRecView = t.tableView(Mappers.ofRowClass(OrderRecord.class));
+
+        OrderRecord orderRecord = orderRecView.get(new OrderRecord(1, 1));
+        binObj = orderRecord.billingDetails;
+
+        // Manual deserialization.
+        Object billingDetails = orderRecord.type == 0 ?
+            binObj.deserialize(CreditCard.class) :
+            binObj.deserialize(BankAccount.class) ;
+    }
+
+    /**
+     * Use case 5: using byte[] and binary objects in columns.
+     * The table has structure
+     * [
+     * [id int, orgId int] // key
+     * [originalObject byte[], upgradedObject byte[], int department] // value
+     * ]
+     * Where {@code originalObject} is some value that was originally put to the column,
+     * {@code upgradedObject} is a version 2 of the object, and department is extracted field.
+     */
+    public void useCase5(Table t) {
+        Row res = t.get(t.createSearchRow(1, 1));
+
+        byte[] objData = res.field("originalObject");
+        BinaryObject binObj = BinaryObjects.wrap(objData);
+        // Work with the binary object as in Ignite 2.x
+
+        // Additionally, we may have a shortcut similar to primitive methods.
+        binObj = res.binaryObjectField("upgradedObject");
+
+        // Plain byte[] and BinaryObject fields in a class are straightforward.
+        class Record {
+            final int id;
+            final int orgId;
+
+            byte[] originalObject;
+            BinaryObject upgradedObject;
+            int department;
+
+            Record(int id, int orgId) {
+                this.id = id;
+                this.orgId = orgId;
+            }
+        }
+
+        TableView<Record> recordView = t.tableView(Mappers.ofRowClass(Record.class));
+
+        // Similarly work with the binary objects.
+        Record rec = recordView.get(new Record(1, 1));
+
+        // Now assume that we have some POJO classes to deserialize the binary objects.
+        class JavaPerson {
+            String name;
+            String lastName;
+        }
+
+        class JavaPersonV2 extends JavaPerson {
+            int department;
+        }
+
+        // We can have a compound record deserializing the whole tuple automatically.
+        class JavaPersonRecord {
+            JavaPerson originalObject;
+            JavaPersonV2 upgradedObject;
+            int department;
+        }
+
+        TableView<JavaPersonRecord> personRecordView = t.tableView(Mappers.ofRowClass(JavaPersonRecord.class));
+
+        // Or we can have an arbitrary record with custom class selection.
+        class TruncatedRecord {
+            JavaPerson upgradedObject;
+            int department;
+        }
+
+        TableView<TruncatedRecord> truncatedView = t.tableView(
+            Mappers.ofRowClassBuilder(TruncatedRecord.class)
+                .deserializing("upgradedObject", JavaPersonV2.class).build());
+
+        // Or we can have a custom conditional type selection.
+        TableView<TruncatedRecord> truncatedView2 = t.tableView(
+            Mappers.ofRowClassBuilder(TruncatedRecord.class)
+                .map("upgradedObject", (row) -> {
+                    BinaryObject bobj = row.binaryObjectField("upgradedObject");
+                    int dept = row.intField("department");
+
+                    return dept == 0 ? bobj.deserialize(JavaPerson.class) : bobj.deserialize(JavaPersonV2.class);
+                }).build());
+    }
+}
+
+
diff --git a/pom.xml b/pom.xml
index 0e6b050..e129595 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,11 +36,12 @@
     <modules>
         <module>modules/cli</module>
         <module>modules/cli-common</module>
+        <module>modules/commons</module>
         <module>modules/configuration</module>
         <module>modules/configuration-annotation-processor</module>
         <module>modules/ignite-runner</module>
     </modules>
-    
+
     <build>
         <plugins>
             <!--