diff --git a/okalitova/pom.xml b/okalitova/pom.xml
index 2ee9231d..ccef77e5 100644
--- a/okalitova/pom.xml
+++ b/okalitova/pom.xml
@@ -16,12 +16,6 @@
UTF-8
-
- junit
- junit
- 3.8.1
- test
-
org.twitter4j
@@ -53,5 +47,17 @@
0.4
+
+ junit
+ junit
+ 4.12
+
+
+
+ com.h2database
+ h2
+ 1.4.190
+
+
diff --git a/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregates.java b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregates.java
new file mode 100644
index 00000000..e0a2d198
--- /dev/null
+++ b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregates.java
@@ -0,0 +1,27 @@
+package ru.fizteh.fivt.students.okalitova.collectionsql;
+
+import ru.fizteh.fivt.students.okalitova.collectionsql.Aggregators.Avg;
+import ru.fizteh.fivt.students.okalitova.collectionsql.Aggregators.Count;
+import ru.fizteh.fivt.students.okalitova.collectionsql.Aggregators.Max;
+import ru.fizteh.fivt.students.okalitova.collectionsql.Aggregators.Min;
+
+import java.util.function.Function;
+
+public class Aggregates {
+ public static Function max(Function expression) {
+ return new Max<>(expression);
+ }
+
+ public static > Function min(Function expression) {
+ return new Min<>(expression);
+ }
+
+ public static Function count(Function expression) {
+ return new Count<>(expression);
+ }
+
+ public static Function avg(Function expression) {
+ return new Avg<>(expression);
+ }
+
+}
diff --git a/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Aggregator.java b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Aggregator.java
new file mode 100644
index 00000000..1109cc26
--- /dev/null
+++ b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Aggregator.java
@@ -0,0 +1,11 @@
+package ru.fizteh.fivt.students.okalitova.collectionsql.Aggregators;
+
+import java.util.List;
+import java.util.function.Function;
+
+/**
+ * Created by nimloth on 16.12.15.
+ */
+public interface Aggregator extends Function {
+ R apply(List elements);
+}
diff --git a/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Avg.java b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Avg.java
new file mode 100644
index 00000000..606af628
--- /dev/null
+++ b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Avg.java
@@ -0,0 +1,33 @@
+package ru.fizteh.fivt.students.okalitova.collectionsql.Aggregators;
+
+/**
+ * Created by nimloth on 17.12.15.
+ */
+import java.util.List;
+import java.util.function.Function;
+
+public class Avg implements Aggregator {
+
+ private Function function;
+ public Avg(Function expression) {
+ this.function = expression;
+ }
+
+ @Override
+ public Double apply(List elements) {
+ return elements
+ .stream()
+ .map(function)
+ .mapToDouble(element -> (Double) element)
+ .average()
+ .getAsDouble();
+ }
+
+ @Override
+ public Double apply(T t) {
+ return null;
+ }
+}
+
+
+
diff --git a/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Count.java b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Count.java
new file mode 100644
index 00000000..ccc24aed
--- /dev/null
+++ b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Count.java
@@ -0,0 +1,30 @@
+package ru.fizteh.fivt.students.okalitova.collectionsql.Aggregators;
+
+import java.util.List;
+import java.util.function.Function;
+
+/**
+ * Created by nimloth on 17.12.15.
+ */
+public class Count implements Aggregator {
+
+ private Function function;
+ public Count(Function expression) {
+ this.function = expression;
+ }
+
+ @Override
+ public Long apply(List elements) {
+ Long longAns = elements
+ .stream()
+ .map(function)
+ .distinct()
+ .count();
+ return longAns;
+ }
+
+ @Override
+ public Long apply(T t) {
+ return null;
+ }
+}
diff --git a/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Max.java b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Max.java
new file mode 100644
index 00000000..a102d8d4
--- /dev/null
+++ b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Max.java
@@ -0,0 +1,29 @@
+package ru.fizteh.fivt.students.okalitova.collectionsql.Aggregators;
+
+import java.util.List;
+import java.util.function.Function;
+
+/**
+ * Created by nimloth on 16.12.15.
+ */
+public class Max> implements Aggregator {
+
+ private Function function;
+ public Max(Function expression) {
+ this.function = expression;
+ }
+
+ @Override
+ public R apply(List elements) {
+ return elements
+ .stream()
+ .map(function)
+ .max(R::compareTo)
+ .get();
+ }
+
+ @Override
+ public R apply(T t) {
+ return null;
+ }
+}
diff --git a/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Min.java b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Min.java
new file mode 100644
index 00000000..00e16c2a
--- /dev/null
+++ b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Aggregators/Min.java
@@ -0,0 +1,29 @@
+package ru.fizteh.fivt.students.okalitova.collectionsql.Aggregators;
+
+import java.util.List;
+import java.util.function.Function;
+
+/**
+ * Created by nimloth on 17.12.15.
+ */
+public class Min> implements Aggregator {
+
+ private Function function;
+ public Min(Function expression) {
+ this.function = expression;
+ }
+
+ @Override
+ public R apply(List elements) {
+ return elements
+ .stream()
+ .map(function)
+ .min(R::compareTo)
+ .get();
+ }
+
+ @Override
+ public R apply(T t) {
+ return null;
+ }
+}
diff --git a/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/CollectionsQL.java b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/CollectionsQL.java
new file mode 100644
index 00000000..46d14e03
--- /dev/null
+++ b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/CollectionsQL.java
@@ -0,0 +1,276 @@
+package ru.fizteh.fivt.students.okalitova.collectionsql;
+
+import java.lang.reflect.InvocationTargetException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+
+/**
+ * Created by nimloth on 16.12.15.
+ */
+public class CollectionsQL {
+
+ public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException,
+ InstantiationException, IllegalAccessException {
+ }
+
+
+ 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);
+ }
+
+ @Override
+ public String toString() {
+ return "Student{"
+ + "name='" + name + '\''
+ + ", dateOfBith=" + dateOfBith
+ + ", group=" + group
+ + '}';
+ }
+
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Student student = (Student) o;
+
+ if (name != null) {
+ if (!name.equals(student.name)) {
+ return false;
+ }
+ } else {
+ if (student.name != null) {
+ return false;
+ }
+ }
+ if (dateOfBith != null) {
+ if (!dateOfBith.equals(student.dateOfBith)) {
+ return false;
+ }
+ } else {
+ if (student.dateOfBith != null) {
+ return false;
+ }
+ }
+ if (group != null) {
+ return !!group.equals(student.group);
+ } else {
+ return !(student.group != null);
+ }
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ if (name != null) {
+ result = name.hashCode();
+ } else {
+ result = 0;
+ }
+ if (dateOfBith != null) {
+ result = 31 * result + dateOfBith.hashCode();
+ } else {
+ result = 31 * result + 0;
+ }
+ if (group != null) {
+ result = 31 * result + group.hashCode();
+ } else {
+ result = 31 * result + 0;
+ }
+ return result;
+ }
+ }
+
+ 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;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Group group1 = (Group) o;
+
+ if (group != null) {
+ if (!group.equals(group1.group)) {
+ return false;
+ }
+ } else {
+ if (group1.group != null) {
+ return false;
+ }
+ }
+ if (mentor != null) {
+ return !!mentor.equals(group1.mentor);
+ } else {
+ return !(group1.mentor != null);
+ }
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ if (group != null) {
+ result = group.hashCode();
+ } else {
+ result = 0;
+ }
+ if (mentor != null) {
+ result = 31 * result + mentor.hashCode();
+ } else {
+ result = 31 * result + 0;
+ }
+ return result;
+ }
+ }
+
+
+ public static class Statistics {
+
+ private final String group;
+ private Long count = Long.valueOf(0);
+ private final Long age;
+
+ public String getGroup() {
+ return group;
+ }
+
+ public Long getCount() {
+ return count;
+ }
+
+ public Long getAge() {
+ return age;
+ }
+
+ public Statistics(String group, Long age, Long count) {
+ 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 o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Statistics that = (Statistics) o;
+
+ if (group != null) {
+ if (!group.equals(that.group)) {
+ return false;
+ }
+ } else {
+ if (that.group != null) {
+ return false;
+ }
+ }
+ if (count != null) {
+ if (!count.equals(that.count)) {
+ return false;
+ }
+ } else {
+ if (that.count != null) {
+ return false;
+ }
+ }
+ if (age != null) {
+ return !!age.equals(that.age);
+ } else {
+ return !(that.age != null);
+ }
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ if (group != null) {
+ result = group.hashCode();
+ } else {
+ result = 0;
+ }
+ if (count != null) {
+ result = 31 * result + count.hashCode();
+ } else {
+ result = 31 * result + 0;
+ }
+ if (age != null) {
+ result = 31 * result + age.hashCode();
+ } else {
+ result = 31 * result + 0;
+ }
+ return result;
+ }
+ }
+
+}
diff --git a/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Conditions.java b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Conditions.java
new file mode 100644
index 00000000..23041f81
--- /dev/null
+++ b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Conditions.java
@@ -0,0 +1,23 @@
+package ru.fizteh.fivt.students.okalitova.collectionsql;
+
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+/**
+ * Created by nimloth on 16.12.15.
+ */
+public class Conditions {
+ public static Predicate rlike(Function expression,
+ String regexp) {
+ return (item -> expression.apply(item).matches(regexp));
+ }
+
+ public static Predicate like(Function expression,
+ String pattern) {
+ return (item -> expression.apply(item).equals(pattern));
+ }
+
+ public static Predicate notNull(Function expression) {
+ return (item -> !expression.apply(item).equals(null));
+ }
+}
diff --git a/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/From.java b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/From.java
new file mode 100644
index 00000000..450b6ef4
--- /dev/null
+++ b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/From.java
@@ -0,0 +1,87 @@
+package ru.fizteh.fivt.students.okalitova.collectionsql;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+
+/**
+ * Created by nimloth on 16.12.15.
+ */
+public class From {
+ private List elements = new ArrayList<>();
+
+ public From(Iterable initElements) {
+ for (T elem : initElements) {
+ elements.add(elem);
+ }
+ }
+
+ public static From from(Iterable iterable) {
+ return new From<>(iterable);
+ }
+
+ public Select select(Class myClass,
+ Function... functions) {
+ return new Select<>(elements, myClass, false, functions);
+ }
+
+ public Select selectDistinct(Class myClass,
+ Function... functions) {
+ return new Select<>(elements, myClass, true, functions);
+ }
+ public final Select> select(Function first, Function second) {
+ return new Select<>(elements, false, first, second);
+ }
+
+
+ public Join join(Iterable iterable) {
+ return new Join<>(elements, iterable);
+ }
+
+ public class Join {
+ private List firstElements = new ArrayList<>();
+ private List secondElements = new ArrayList<>();
+ private List> elements = new ArrayList<>();
+ Join(List initElements, Iterable initIterable) {
+ for (T elem : initElements) {
+ firstElements.add(elem);
+ }
+ for (J it : initIterable) {
+ secondElements.add(it);
+ }
+ }
+ public From> on(BiPredicate predicate) {
+ for (T first : firstElements) {
+ for (J second : secondElements) {
+ if (predicate.test(first, second)) {
+ elements.add(new Tuple<>(first, second));
+ }
+ }
+ }
+ return new From<>(elements);
+ }
+
+ public > From> on(
+ Function leftKey,
+ Function rightKey) {
+ HashMap> map = new HashMap<>();
+ for (J element : secondElements) {
+ K key = rightKey.apply(element);
+ if (!map.containsKey(key)) {
+ map.put(key, new ArrayList<>());
+ }
+ map.get(key).add(element);
+ }
+ for (T first : firstElements) {
+ K key = leftKey.apply(first);
+ if (map.containsKey(key)) {
+ List second = map.get(key);
+ second.forEach(s -> elements.add(new Tuple<>(first, s)));
+ }
+ }
+ return new From<>(elements);
+ }
+ }
+}
diff --git a/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/OrderByConditions.java b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/OrderByConditions.java
new file mode 100644
index 00000000..61790c13
--- /dev/null
+++ b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/OrderByConditions.java
@@ -0,0 +1,17 @@
+package ru.fizteh.fivt.students.okalitova.collectionsql;
+
+import java.util.Comparator;
+import java.util.function.Function;
+
+/**
+ * Created by nimloth on 17.12.15.
+ */
+public class OrderByConditions {
+ public static > Comparator asc(Function expression) {
+ return (o1, o2) -> expression.apply(o1).compareTo(expression.apply(o2));
+ }
+
+ public static > Comparator desc(Function expression) {
+ return (o1, o2) -> expression.apply(o2).compareTo(expression.apply(o1));
+ }
+}
diff --git a/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Select.java b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Select.java
new file mode 100644
index 00000000..d46f22d9
--- /dev/null
+++ b/okalitova/src/main/java/ru/fizteh/fivt/students/okalitova/collectionsql/Select.java
@@ -0,0 +1,175 @@
+package ru.fizteh.fivt.students.okalitova.collectionsql;
+
+import ru.fizteh.fivt.students.okalitova.collectionsql.Aggregators.Aggregator;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * Created by nimloth on 16.12.15.
+ */
+public class Select {
+ private Iterable iterable;
+ private Class myClass;
+ private Class joinClass;
+ private boolean distinct;
+ private boolean isJoin = false;
+ private Function[] functions;
+
+ private Predicate wherePredicate;
+ private Predicate havingPredicate;
+
+ private int limit = -1;
+ private Function[] groupByFunctions;
+ private Comparator[] comporators;
+
+
+ public Select(Iterable initIterable,
+ Class initClass,
+ boolean initDistinct,
+ Function[] initFunctions) {
+ iterable = initIterable;
+ myClass = initClass;
+ distinct = initDistinct;
+ functions = initFunctions;
+ }
+
+ public Select(List initElements, boolean isDistinct, Function first, Function second) {
+ iterable = initElements;
+ joinClass = initElements.get(0).getClass();
+ distinct = isDistinct;
+ functions = new Function[]{first, second};
+ isJoin = true;
+ }
+
+ public Select where(Predicate initPredicate) {
+ wherePredicate = initPredicate;
+ return this;
+ }
+
+ public Select limit(int initLimit) {
+ limit = initLimit;
+ return this;
+ }
+
+ public Select groupBy(Function... initGroupByFunctions) {
+ groupByFunctions = initGroupByFunctions;
+ distinct = true;
+ return this;
+ }
+
+ public Select having(Predicate initHavingPredicate) {
+ havingPredicate = initHavingPredicate;
+ return this;
+ }
+
+ public Select orderBy(Comparator... initComparators) {
+ comporators = initComparators;
+ return this;
+ }
+
+ public List execute() throws IllegalAccessException,
+ InvocationTargetException, InstantiationException {
+ List elements = new ArrayList<>();
+ for (T it : iterable) {
+ elements.add(it);
+ }
+
+ if (wherePredicate != null) {
+ elements = elements.stream().filter(wherePredicate).collect(Collectors.toList());
+ }
+
+ if (distinct) {
+ elements = elements.stream().distinct().collect(Collectors.toList());
+ }
+
+ if (limit != -1) {
+ elements = elements.stream().limit(limit).collect(Collectors.toList());
+ }
+
+ Map> resultMap = new HashMap<>();
+ if (groupByFunctions != null) {
+ Map> groupByResult = elements.stream().collect(Collectors.groupingBy((T elem) -> {
+ List