Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions nmakeenkov/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,34 @@
<version>20090211</version>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
</dependency>


<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>


<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>

</dependencies>

<developers>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package ru.fizteh.fivt.students.nmakeenkov.collectionquery;

import java.util.List;
import java.util.function.Function;

/**
* Aggregate functions.
*
* @author akormushin
*/
public class Aggregates {

/**
* Maximum value for expression for elements of given collecdtion.
*
* @param expression
* @param <C>
* @param <T>
* @return
*/
public static <C, T extends Comparable<T>> Function<C, T> max(Function<C, T> expression) {
return new AggregationFunction<C, T>() {
private Function<C, T> converter = expression;

@Override
public T apply(List<C> list) {
T result = null;
for (C element : list) {
if (result == null) {
result = converter.apply(element);
} else {
T currentResult = converter.apply(element);
if (currentResult.compareTo(result) > 0) {
result = currentResult;
}
}
}
return result;
}

@Override
public T apply(C c) {
return null;
}
};
}

/**
* Minimum value for expression for elements of given collecdtion.
*
* @param expression
* @param <C>
* @param <T>
* @return
*/
public static <C, T extends Comparable<T>> Function<C, T> min(Function<C, T> expression) {
return new AggregationFunction<C, T>() {
private Function<C, T> converter = expression;

@Override
public T apply(List<C> list) {
T result = null;
for (C element : list) {
if (result == null) {
result = converter.apply(element);
} else {
T currentResult = converter.apply(element);
if (currentResult.compareTo(result) < 0) {
result = currentResult;
}
}
}
return result;
}

@Override
public T apply(C c) {
return null;
}
};
}

/**
* Number of items in source collection that turns this expression into not null.
*
* @param expression
* @param <C>
* @return
*/
public static <C> Function<C, Integer> count(Function<C, ?> expression) {
return new AggregationFunction<C, Integer>() {
@Override
public Integer apply(List<C> list) {
return list.size();
}

@Override
public Integer apply(C c) {
return null;
}
};
}

/**
* Average value for expression for elements of given collection.
*
* @param expression
* @param <C>
* @return
*/
public static <C> Function<C, Double> avg(Function<C, ? extends Number> expression) {
return new AggregationFunction<C, Double>() {
private Function<C, ? extends Number> converter = expression;

@Override
public Double apply(List<C> list) {
Double result = 0d;
for (C element : list) {
result += converter.apply(element).doubleValue();
}
result /= list.size();
return result;
}

@Override
public Double apply(C t) {
return null;
}
};
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.fizteh.fivt.students.nmakeenkov.collectionquery;

import java.util.List;
import java.util.function.Function;

public interface AggregationFunction<T, E> extends Function<T, E> {
E apply(List<T> list);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package ru.fizteh.fivt.students.nmakeenkov.collectionquery;

import org.apache.commons.lang3.builder.HashCodeBuilder;
import ru.fizteh.fivt.students.nmakeenkov.collectionquery.impl.Tuple;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Objects;

import static ru.fizteh.fivt.students.nmakeenkov.collectionquery.Aggregates.avg;
import static ru.fizteh.fivt.students.nmakeenkov.collectionquery.Aggregates.count;
import static ru.fizteh.fivt.students.nmakeenkov.collectionquery.CollectionQuery.Student.student;
import static ru.fizteh.fivt.students.nmakeenkov.collectionquery.Conditions.rlike;
import static ru.fizteh.fivt.students.nmakeenkov.collectionquery.OrderByConditions.asc;
import static ru.fizteh.fivt.students.nmakeenkov.collectionquery.OrderByConditions.desc;
import static ru.fizteh.fivt.students.nmakeenkov.collectionquery.Sources.list;
import static ru.fizteh.fivt.students.nmakeenkov.collectionquery.impl.FromStmt.from;

/**
* @author akormushin
*/
public class CollectionQuery {

/**
* Make this code work!
*
* @param args
*/
public static void main(String[] args) throws Exception {
Iterable<Statistics> statistics =
from(list(
student("ivanov", LocalDate.parse("1986-08-06"), "494"),
student("sidorov", LocalDate.parse("1986-08-06"), "495"),
student("smith", LocalDate.parse("1986-08-06"), "495"),
student("petrov", LocalDate.parse("2006-08-06"), "494")))
.select(Statistics.class, Student::getGroup, count(Student::getGroup), avg(Student::age))
.where(rlike(Student::getName, ".*ov").and(s -> s.age() > 20))
.groupBy(Student::getGroup)
.having(s -> s.getCount() > 0)
.orderBy(asc(Statistics::getGroup), desc(Statistics::getCount))
.limit(100)
.union()
.from(list(student("ivanov", LocalDate.parse("1985-08-06"), "494")))
.selectDistinct(Statistics.class, s -> "all", count(s -> 1), avg(Student::age))
.execute();
System.out.println(statistics);

Iterable<Tuple<String, String>> mentorsByStudent =
from(list(student("ivanov", LocalDate.parse("1985-08-06"), "494")))
.join(list(new Group("494", "mr.sidorov")))
.on((s, g) -> Objects.equals(s.getGroup(), g.getGroup()))
.select(sg -> sg.getFirst().getName(), sg -> sg.getSecond().getMentor())
.execute();
System.out.println(mentorsByStudent);
}


public static class Student {
private final String name;

private final LocalDate dateOfBith;

private final String group;

public String getName() {
return name;
}

public Student(String name, LocalDate dateOfBith, String group) {
this.name = name;
this.dateOfBith = dateOfBith;
this.group = group;
}

public LocalDate getDateOfBith() {
return dateOfBith;
}

public String getGroup() {
return group;
}

public long age() {
return ChronoUnit.YEARS.between(getDateOfBith(), LocalDateTime.now());
}

public static Student student(String name, LocalDate dateOfBith, String group) {
return new Student(name, dateOfBith, group);
}
}

public static class Group {
private final String group;
private final String mentor;

public Group(String group, String mentor) {
this.group = group;
this.mentor = mentor;
}

public String getGroup() {
return group;
}

public String getMentor() {
return mentor;
}
}


public static class Statistics {

private final String group;
private final Integer count;
private final Double age;

public String getGroup() {
return group;
}

public Integer getCount() {
return count;
}

public Double getAge() {
return age;
}

public Statistics(String group, Integer count, Double age) {
this.group = group;
this.count = count;
this.age = age;
}

@Override
public String toString() {
return "Statistics{"
+ "group='" + group + '\''
+ ", count=" + count
+ ", age=" + age
+ '}';
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof Statistics)) {
return false;
}
Statistics oth = (Statistics) obj;
return this.group.equals(oth.getGroup())
&& this.age.equals(oth.getAge())
&& this.count.equals(oth.getCount());
}

@Override
public int hashCode() {
return new HashCodeBuilder(227, 229)
.append(group)
.append(count)
.append(age)
.toHashCode();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ru.fizteh.fivt.students.nmakeenkov.collectionquery;

import java.util.function.Function;
import java.util.function.Predicate;

/**
* Where clause conditions.
*
* @author akormushin
*/
public class Conditions<T> {

/**
* Matches string result of expression against regexp pattern.
*
* @param expression expression result to match
* @param regexp pattern to match to
* @param <T> source object type
* @return
*/
public static <T> Predicate<T> rlike(Function<T, String> expression, String regexp) {
return (object) -> (expression.apply(object).matches(regexp));
}

/**
* Matches string result of expression against SQL like pattern.
*
* @param expression expression result to match
* @param pattern pattern to match to
* @param <T> source object type
* @return
*/
public static <T> Predicate<T> like(Function<T, String> expression, String pattern) {
throw new UnsupportedOperationException();
}

}
Loading