Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

72 Commits

Repository files navigation

Heterogeneous and type-safe tables

build statuscodecov

Motivation

This project is aimed to experiment with the implementation of heterogeneous yet type-safe table structure.

As of now, the API makes able to:

  • create heterogeneous tables,
  • modify them and their content,
  • query their content in a type-safe way.

Full example

Because code is better than words, here is a quick overview of the API:

ColumnId<Integer> AGE = id("age", Integer.class);
ColumnId<String> NAME = id("name", String.class);
Tablepeople = newDataTable();
people.columns()
.create(NAME, "Luc", "Baptiste", "Marie")
.create(AGE, 23, 32, 42);
TableadultsWhoseNameEndsWithLetterE = people.filter(row ->
row.get(AGE) > 18 &&
row.get(NAME).startsWith("E")
);

Quick start

Understanding ids

Ids can be seen as references, as keys used to identify specific columns within a table. They are tricks used to provide a type-safe way to access the content of a table.

Basically, they are simple data structure containing:

  • a type, that is the Java class of the column's elements
  • a header, that is the name of the column.

An id is represented by the ColumnId class and can be created with the id static method :

// name is an id that matches any column containing Strings and which header is "col1"ColumnId<String> name = ColumnId.id("col1", String.class);

In the following document, ids are used everywhere. However, although they are the advised way to deal with a table, they can always be replaced by indexes or column names.

Populating a Table

Creation of a new Table consists of an easy one-liner :

Tablepeople = newDataTable();

A table can be filled either by adding new columns :

people.columns()
.create("Name", String.class, "Luc", "Baptiste", "Marie")
.create("Age", Integer.class, 23, 32, 42);

or by adding new rows :

people.rows()
.create("Julie", 12)
.create("Mathieu", 67);

The table resulting of the above statements is the following :

+----------+-----+
| Name | Age |
+----------+-----|
| Luc | 23 |
| Baptiste | 32 |
| Marie | 42 |
| Julie | 12 |
| Mathieu | 67 |
+----------+-----+

Depopulating a Table

A table can be emptied either by removing columns :

people.columns()
.remove("age");

or by removing rows :

people.rows()
.remove(4)
.remove(2);

Notice how the last row has been removed first in order to avoid bugs related to changes of ids. The table now looks like :

+----------+
| Name |
+----------+
| Luc |
| Baptiste |
| Julie |
+----------+

Querying a Table

The filter method makes easy to retrieve the rows of a table that match a specific criterion:

importstaticfr.kazejiyu.generic.datatable.core.impl.ColumnId.*;
publicclassMain {
// Reference table's columnsprivatestaticfinalColumnId<Integer> AGE = id("age", Integer.class);
privatestaticfinalColumnId<String> NAME = id("name", String.class);
TableadultsWhoseNameEndsWithLetterE(Tablepeople) {
returnpeople.filter(row ->
row.get(AGE) > 18 &&
row.get(NAME).startsWith("E")
);
}
}

SQL-like DSL

For more complex cases, the API also brings a SQL-like DSL that makes possible to apply a same filter to multiple columns. It can be used as follows :

importstaticfr.kazejiyu.generic.datatable.core.impl.ColumnId.*;
publicclassMain {
// Reference table's columnsprivatestaticfinalColumnId<Integer> AGE = id("age", Integer.class);
privatestaticfinalColumnId<String> NAME = id("name", String.class);
privatestaticfinalColumnId<String> SURENAME = id("surename", String.class);
// Retrieve all european adults whose both name and surename ends with the letter "e"TableadultsWhoseNameEndsWithLetterE(Tablepeople) {
returnQuery
.from(people)
.where(s(NAME, SURENAME)).endsWith("e")
.and(AGE).gt(18)
.and(COUNTRY).match(Country::isInEurope)
.select();
}
}

Notice how the s method is used to specify that the columns concerning by the WHERE clause contain String instances. That makes possible to use tailored methods (such as endsWith in the above example) ; because of Java's type erasure, this trick is mandatory. This static method is defined in the ColumnId class, as well as the methods:

  • n: used to apply a same filter to several columns of numbers,
  • b: used to apply a same filter to several columns of booleans.

About

Heterogeneous and type-safe table structure

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages