diff --git a/projects/checkstyle.xml b/projects/checkstyle.xml
index 3401cf5..72e7ecc 100644
--- a/projects/checkstyle.xml
+++ b/projects/checkstyle.xml
@@ -88,85 +88,85 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
+
-
-
-
+
+
+
diff --git a/projects/pom.xml b/projects/pom.xml
index 5d14966..511d9d4 100644
--- a/projects/pom.xml
+++ b/projects/pom.xml
@@ -30,6 +30,7 @@
dkhurtin
ale3otik
Pitovsky
+ simon23rus
diff --git a/projects/simon23rus/dbTask.mv.db b/projects/simon23rus/dbTask.mv.db
new file mode 100644
index 0000000..7215bfd
Binary files /dev/null and b/projects/simon23rus/dbTask.mv.db differ
diff --git a/projects/simon23rus/dbTask.trace.db b/projects/simon23rus/dbTask.trace.db
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/projects/simon23rus/dbTask.trace.db
@@ -0,0 +1 @@
+
diff --git a/projects/simon23rus/pom.xml b/projects/simon23rus/pom.xml
new file mode 100644
index 0000000..d243e87
--- /dev/null
+++ b/projects/simon23rus/pom.xml
@@ -0,0 +1,113 @@
+
+ 4.0.0
+
+
+ ru.mipt.diht.students
+ parent
+ 1.0-SNAPSHOT
+
+
+ ru.mipt.diht.students
+ simon23rus
+ 1.0-SNAPSHOT
+ simon23rus
+ http://maven.apache.org
+
+
+
+
+
+ org.twitter4j
+ twitter4j-core
+ [4.0,)
+
+
+
+ org.twitter4j
+ twitter4j-stream
+ [4.0,)
+
+
+
+ com.beust
+ jcommander
+ 1.48
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+ org.mockito
+ mockito-core
+ 1.10.8
+ test
+
+
+ objenesis
+ org.objenesis
+
+
+
+
+ com.h2database
+ h2
+ 1.4.190
+
+
+ com.google.guava
+ guava
+ 19.0
+
+
+ org.powermock
+ powermock-module-junit4
+ 1.6.1
+ test
+ true
+
+
+
+ org.powermock
+ powermock-api-mockito
+ 1.6.1
+ test
+ true
+
+
+ mockito-all
+ org.mockito
+
+
+
+
+
+
+ commons-io
+ commons-io
+ 2.4
+ test
+
+
+
+
+
+
+ maven-compiler-plugin
+ 3.1
+
+ 1.8
+ 1.8
+
+
+
+
+ mipt
+
+
+
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/Aggregates.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/Aggregates.java
new file mode 100644
index 0000000..4b2dd74
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/Aggregates.java
@@ -0,0 +1,60 @@
+package ru.mipt.diht.students.simon23rus.CQL.data;
+
+import ru.mipt.diht.students.simon23rus.CQL.implOfAggregators.Avg;
+import ru.mipt.diht.students.simon23rus.CQL.implOfAggregators.Count;
+import ru.mipt.diht.students.simon23rus.CQL.implOfAggregators.Max;
+import ru.mipt.diht.students.simon23rus.CQL.implOfAggregators.Min;
+
+import java.util.function.Function;
+
+/**
+ * Aggregate functions.
+ */
+public class Aggregates {
+
+ /**
+ * Maximum value for expression for elements of given collecdtion.
+ *
+ * @param expression
+ * @param
+ * @return
+ */
+ public static Function max(Function expression) {
+ return new Max<>(expression);
+ }
+
+ /**
+ * Minimum value for expression for elements of given collecdtion.
+ *
+ * @param expression
+ * @param
+ * @param
+ * @return
+ */
+ public static > Function min(Function expression) {
+ return new Min<>(expression);
+ }
+
+ /**
+ * Number of items in source collection that turns this expression into not null.
+ *
+ * @param expression
+ * @param
+ * @return
+ */
+ public static Function count(Function expression) {
+ return new Count<>(expression);
+ }
+
+ /**
+ * Average value for expression for elements of given collection.
+ *
+ * @param expression
+ * @param
+ * @return
+ */
+ public static Function avg(Function expression) {
+ return new Avg<>(expression);
+ }
+
+}
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/CollectionQuery.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/CollectionQuery.java
new file mode 100644
index 0000000..5606fc3
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/CollectionQuery.java
@@ -0,0 +1,179 @@
+package ru.mipt.diht.students.simon23rus.CQL.data;
+
+import ru.mipt.diht.students.simon23rus.CQL.impl.*;
+import static ru.mipt.diht.students.simon23rus.CQL.data.Sources.list;
+
+import java.lang.reflect.InvocationTargetException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.Objects;
+
+//import static ru.mipt.diht.students.simon23rus.data.CollectionQuery.Student.student;
+
+
+public class CollectionQuery {
+
+
+//
+// public static void main(String[] args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
+//
+//// Iterable> mentorsByStudent =
+//// FromStmt.from(list(Student.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 dateOfBirth;
+
+ private final String group;
+
+ public Student(String name, LocalDate dateOfBirth, String group) {
+ this.name = name;
+ this.dateOfBirth = dateOfBirth;
+ this.group = group;
+ }
+
+ public Student(String name, String group) {
+ this.name = name;
+ this.group = group;
+ this.dateOfBirth = LocalDate.now();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public LocalDate getDateOfBirth() {
+ return dateOfBirth;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public Double age() {
+ return ((double) ChronoUnit.YEARS.between(getDateOfBirth(), LocalDateTime.now()));
+ }
+
+ public static Student student(String name, LocalDate dateOfBith, String group) {
+ return new Student(name, dateOfBith, group);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder toReturn = new StringBuilder("Students{");
+ if(!group.equals(0)) {
+ toReturn.append("group=").append(this.group).append(",");
+ }
+ if(!name.equals(0)) {
+ toReturn.append("name=").append(this.name).append(",");
+ }
+ if(!dateOfBirth.equals(0)) {
+ toReturn.append("dateOfBirth=").append(this.dateOfBirth).append(",");
+ }
+ toReturn.append("}");
+ return toReturn.toString();
+ }
+ }
+
+
+ public static class Statistics {
+
+ private final String group;
+ private final Long count;
+ private final Double age;
+
+ public String getGroup() {
+ return group;
+ }
+
+ public Long getCount() {
+ return count;
+ }
+
+ public Double getAge() {
+ return age;
+ }
+
+ public Statistics(String group, Long count, Double age) {
+ this.group = group;
+ this.count = count;
+ this.age = age;
+ }
+
+ public Statistics(String group, Long count) {
+ this(group, count, 18D);
+ }
+
+ public Statistics(String group, Double age) {
+ this(group, 1L, age);
+ }
+
+ public Statistics(String group) {
+ this(group, 1L, 2D);
+ }
+
+ public Statistics(Double age) {
+ this("sad", 0L, age);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder toReturn = new StringBuilder("Statistics{");
+ if(!group.equals(0)) {
+ toReturn.append("group= ").append(this.group).append("");
+ }
+ if(!count.equals(0)) {
+ toReturn.append("count= ").append(this.count).append("");
+ }
+ if(!age.equals(0)) {
+ toReturn.append("age= ").append(this.age).append("");
+ }
+ toReturn.append("}");
+ return toReturn.toString();
+ }
+ }
+
+ public static class Group {
+ private final String group;
+ private final String mentor;
+
+ public Group(String myGroup, String myMentor) {
+ this.group = myGroup;
+ this.mentor = myMentor;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public String getMentor() {
+ return mentor;
+ }
+ public static Group group(String myGroup, String myMentor) {
+ return new Group(myGroup, myMentor);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder().append("Student{");
+ if (group != null) {
+ result.append("group=").append(group).append(",");
+ }
+ if (mentor != null) {
+ result.append(", name=").append(mentor);
+ }
+ result.append("}\n");
+ return result.toString();
+ }
+ }
+
+}
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/Conditions.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/Conditions.java
new file mode 100644
index 0000000..4bb81eb
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/Conditions.java
@@ -0,0 +1,36 @@
+package ru.mipt.diht.students.simon23rus.CQL.data;
+
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+/**
+ * Where clause conditions.
+ */
+public class Conditions {
+
+ /**
+ * Matches string result of expression against regexp pattern.
+ *
+ * @param expression expression result to match
+ * @param regexp pattern to match to
+ * @param source object type
+ * @return
+ */
+ public static Predicate rlike(Function expression, String regexp) {
+ return elem -> expression.apply(elem).matches(regexp);
+ }
+
+ /**
+ * Matches string result of expression against SQL like pattern.
+ *
+ * @param expression expression result to match
+ * @param pattern pattern to match to
+ * @param source object type
+ * @return
+
+ */
+// public static Predicate like(Function expression, String pattern) {
+// return Predicate.isEqual()
+// }
+
+}
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/OrderByConditions.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/OrderByConditions.java
new file mode 100644
index 0000000..99c905e
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/OrderByConditions.java
@@ -0,0 +1,35 @@
+package ru.mipt.diht.students.simon23rus.CQL.data;
+
+import java.util.Comparator;
+import java.util.function.Function;
+
+/**
+ * OrderBy sort order helper methods.
+ */
+public class OrderByConditions {
+
+ /**
+ * Ascending comparator.
+ *
+ * @param expression
+ * @param
+ * @param
+ * @return
+ */
+ public static > Comparator asc(Function expression) {
+ return (o1, o2) -> expression.apply(o1).compareTo(expression.apply(o2));
+ }
+
+ /**
+ * Descending comparator.
+ *
+ * @param expression
+ * @param
+ * @param
+ * @return
+ */
+ public static > Comparator desc(Function expression) {
+ return (o1, o2) -> expression.apply(o2).compareTo(expression.apply(o1));
+ }
+
+}
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/Sources.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/Sources.java
new file mode 100644
index 0000000..ac22549
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/data/Sources.java
@@ -0,0 +1,49 @@
+package ru.mipt.diht.students.simon23rus.CQL.data;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Helper methods to create collections.
+ */
+public class Sources {
+
+ /**
+ * @param items
+ * @param
+ * @return
+ */
+ @SafeVarargs
+ public static List list(T... items) {
+ return Arrays.asList(items);
+ }
+
+// /**
+// * @param items
+// * @param
+// * @return
+// */
+// @SafeVarargs
+// public static Set set(T... items) {
+// throw new UnsupportedOperationException();
+// }
+//
+// /**
+// * @param inputStream
+// * @param
+// * @return
+// */
+// public static Stream lines(InputStream inputStream) {
+// throw new UnsupportedOperationException();
+// }
+//
+// /**
+// * @param file
+// * @param
+// * @return
+// */
+// public static Stream lines(Path file) {
+// throw new UnsupportedOperationException();
+// }
+//
+}
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/BestComparatorEver.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/BestComparatorEver.java
new file mode 100644
index 0000000..6dcbc1d
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/BestComparatorEver.java
@@ -0,0 +1,24 @@
+package ru.mipt.diht.students.simon23rus.CQL.impl;
+
+import java.util.Comparator;
+
+public class BestComparatorEver implements Comparator {
+ Comparator[] currentComparators;
+
+ BestComparatorEver(Comparator... givenComparators) {
+ currentComparators = givenComparators;
+ }
+
+ @Override
+ public int compare(R first, R second) {
+ for(Comparator thisComparator : currentComparators) {
+ int comparisonResult = thisComparator.compare(first, second);
+ if(comparisonResult != 0) {
+ return comparisonResult;
+ }
+ }
+
+ return 0;
+ }
+
+}
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/FromStmt.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/FromStmt.java
new file mode 100644
index 0000000..218f8f4
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/FromStmt.java
@@ -0,0 +1,92 @@
+package ru.mipt.diht.students.simon23rus.CQL.impl;
+
+import java.util.*;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+
+public class FromStmt {
+
+ private List data = new ArrayList();
+
+ public List getData() {
+ return data;
+ }
+
+ public FromStmt(Iterable toIterate) {
+ toIterate.forEach(e -> data.add(e));
+ }
+
+ public FromStmt(Stream myStream) {
+ myStream.forEach(e -> data.add(e));
+ }
+
+
+ public static FromStmt from(Iterable iterable) {
+ return new FromStmt(iterable);
+ }
+
+ public static FromStmt from(Stream stream) {
+ return new FromStmt(stream);
+ }
+
+ @SafeVarargs
+ public final SelectStmt select(Class clazz, Function... s) {
+ return new SelectStmt<>(data, clazz, false, s);
+ }
+
+ @SafeVarargs
+ public final SelectStmt selectDistinct(Class clazz, Function... s) {
+ return new SelectStmt<>(data, clazz, true, s);
+ }
+
+ public final SelectStmt> select(Function first, Function second) {
+ return new SelectStmt<>(data, false, first, second);
+ }
+
+ public JoinClause join(Iterable iterable) {
+ return new JoinClause(data, iterable);
+ }
+
+ public class JoinClause {
+
+ private List firstElements = new ArrayList<>();
+ private List secondElements = new ArrayList<>();
+ private List> joinedElements = new ArrayList<>();
+
+ public JoinClause(List firstElements, Iterable secondElements) {
+ this.firstElements
+ .addAll(firstElements.stream()
+ .collect(Collectors.toList()));
+ for (J curr : secondElements) {
+ this.secondElements.add(curr);
+ }
+ }
+
+ public FromStmt> on(BiPredicate condition) {
+ firstElements.forEach(first ->
+ secondElements.forEach(second -> {
+ if (condition.test(first, second)) {
+ this.joinedElements.add(new Tuple<>(first, second));
+ }
+ }));
+ return new FromStmt<>(joinedElements);
+ }
+
+ public > FromStmt> on(
+ Function leftKey,
+ Function rightKey) {
+ Map> leftMap = firstElements.stream().collect(Collectors.groupingBy(leftKey));
+ Map> rightMap = secondElements.stream().collect(Collectors.groupingBy(rightKey));
+ leftMap.forEach((key, value) -> {
+ if (rightMap.containsKey(key)) {
+ value.forEach(fst -> rightMap.get(key).forEach(snd -> joinedElements.add(new Tuple(fst, snd))));
+ }
+ });
+ return new FromStmt<>(joinedElements);
+ }
+ }
+
+}
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/SelectStmt.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/SelectStmt.java
new file mode 100644
index 0000000..e8cfe89
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/SelectStmt.java
@@ -0,0 +1,253 @@
+package ru.mipt.diht.students.simon23rus.CQL.impl;
+
+import javafx.util.Pair;
+import ru.mipt.diht.students.simon23rus.CQL.implOfAggregators.Aggregator;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class SelectStmt {
+ public boolean isDistinct;
+ public boolean isUnion;
+ public boolean isJoin;
+ int maxRawsNeeded;
+ Predicate whereRestriction;
+ Predicate havingRestriction;
+ Function[] currentFunctions;
+ Function[] groupByExpressions;
+ Class toReturn;
+ Comparator[] orderByComparators;
+ BestComparatorEver bestComparatorEver;
+ List oldData;
+ List currentData;
+ Stream toStream;
+
+ @SafeVarargs
+ public SelectStmt(List elements, Class returnClass, boolean isDistinct, Function... functions) {
+ this.oldData = new ArrayList<>();
+ this.currentData = elements;
+ this.toReturn = returnClass;
+ this.isDistinct = isDistinct;
+ this.currentFunctions = functions;
+ this.maxRawsNeeded = -1;
+ this.isUnion = false;
+ this.isJoin = false;
+ }
+
+ public SelectStmt(List elements, boolean isDistinct, Function first, Function second) {
+ this.oldData = new ArrayList<>();
+ this.currentData = elements;
+ this.toReturn = elements.get(0).getClass();
+ this.isDistinct = isDistinct;
+ this.currentFunctions = new Function[]{first, second};
+ this.maxRawsNeeded = -1;
+ this.isUnion = false;
+ this.isJoin = true;
+ }
+
+ @SafeVarargs
+ public SelectStmt(List pastElements, List elements, Class returnClass,
+ boolean isDistinct, Function... functions) {
+ this.currentData = elements;
+ this.toReturn = returnClass;
+ this.isDistinct = isDistinct;
+ this.currentFunctions = functions;
+ this.maxRawsNeeded = -1;
+ this.isUnion = true;
+ this.isJoin = false;
+ this.oldData = pastElements;
+ }
+
+ public SelectStmt(List pastElements, List elements, boolean isDistinct, Function first,
+ Function second) {
+ this.currentData = elements;
+ this.toReturn = elements.get(0).getClass();
+ this.isDistinct = isDistinct;
+ this.currentFunctions = new Function[]{first, second};
+ this.maxRawsNeeded = -1;
+ this.isUnion = true;
+ this.isJoin = true;
+ this.oldData = pastElements;
+ }
+
+ public int getMaxRawsNeeded() {
+ return maxRawsNeeded;
+ }
+
+ public Class getToReturn() {
+ return toReturn;
+ }
+
+ public Function[] getCurrentFunctions() {
+ return currentFunctions;
+ }
+
+ public List getCurrentData() {
+ return currentData;
+ }
+
+
+
+ public SelectStmt where(Predicate predicate) {
+ this.whereRestriction = predicate;
+ return this;
+ }
+
+ public Iterable execute() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
+ List execResult = new ArrayList<>();
+ Class[] returnClasses = new Class[currentFunctions.length];
+ Object[] arguments = new Object[currentFunctions.length];
+ if(whereRestriction != null) {
+ //nuzhno otfiltrovat' dannie;
+ List filteredData = currentData.stream()
+ .filter(whereRestriction::test)
+ .collect(Collectors.toList());
+ currentData = filteredData;
+ }
+ if(groupByExpressions != null) {
+ Map mapped = new HashMap<>();
+ List> groupedElements = new ArrayList<>();
+ List> grouped = new ArrayList<>();
+ String[] results = new String[groupByExpressions.length];
+ currentData.stream().forEach(
+ element -> {
+ for (int i = 0; i < groupByExpressions.length; i++) {
+ results[i] = (String) groupByExpressions[i].apply(element);
+ }
+ if (!mapped.containsKey(Objects.hash(results))) {
+ mapped.put(Objects.hash(results), mapped.size());
+ }
+ grouped.add(new Pair(element, mapped.get(Objects.hash(results))));
+ }
+ );
+ //dlya togo chtoby kazhdomu elementu iz mapa sootvetstovalo otvetvleniye
+ for (int i = 0; i < mapped.size(); i++) {
+ groupedElements.add(new ArrayList());
+ }
+
+ for (Pair element : grouped) {
+ groupedElements.get(element.getValue()).add(element.getKey());
+ }
+ for (List group : groupedElements) {
+ int counter = 0;
+ for (Function thisFunction : this.currentFunctions) {
+ arguments[counter] = (thisFunction instanceof Aggregator) ? ((Aggregator) thisFunction).apply(group) : thisFunction.apply(group.get(0));
+ returnClasses[counter] = arguments[counter].getClass();
+ ++counter;
+ }
+ if(isJoin) {
+ Tuple newElement = new Tuple(arguments[0], arguments[1]);
+ execResult.add((R) newElement);
+ }
+ else {
+ R newElement = (R) toReturn.getConstructor(returnClasses).newInstance(arguments);
+ execResult.add(newElement);
+ }
+ }
+ }
+
+
+ else {
+
+ for(T elem : currentData) {
+ int counter = 0;
+ for (Function thisFunction : this.currentFunctions) {
+ List thisElement = new ArrayList<>();
+ thisElement.add(elem);
+ arguments[counter] = (thisFunction instanceof Aggregator) ? ((Aggregator) thisFunction).apply(thisElement) : thisFunction.apply(elem);
+ returnClasses[counter] = arguments[counter].getClass();
+ ++counter;
+ }
+ if(isJoin) {
+ Tuple newElement = new Tuple(arguments[0], arguments[1]);
+ execResult.add((R) newElement);
+ }
+ else {
+ R newElement = (R) toReturn.getConstructor(returnClasses).newInstance(arguments);
+ execResult.add(newElement);
+ }
+ }
+
+ }
+
+ if (havingRestriction != null) {
+ List filteredData = execResult.stream()
+ .filter(havingRestriction::test)
+ .collect(Collectors.toList());
+ execResult = filteredData;
+ }
+
+ if (isDistinct) {
+ System.out.println(execResult);
+ Set hashes = new HashSet<>();
+ List distincted = new ArrayList<>();
+ for (R element : execResult) {
+ if (!hashes.contains(element.toString().hashCode())) {
+ hashes.add(element.toString().hashCode());
+ distincted.add(element);
+ }
+ }
+ execResult = distincted;
+ }
+
+ if (orderByComparators != null) {
+ execResult.sort(bestComparatorEver);
+ }
+
+ if (maxRawsNeeded != -1) {
+ if(maxRawsNeeded < execResult.size())
+ execResult = execResult.subList(0, maxRawsNeeded);
+ }
+
+ System.out.println(execResult.size());
+
+ if (isUnion) {
+ oldData.addAll(execResult);
+ execResult = oldData;
+ }
+
+ System.out.println(execResult.size());
+
+ return execResult;
+ }
+
+ @SafeVarargs
+ public final SelectStmt groupBy(Function... expressions) {
+ this.groupByExpressions = expressions;
+ return this;
+ }
+
+ @SafeVarargs
+ public final SelectStmt orderBy(Comparator... comparators) {
+ this.orderByComparators = comparators;
+ this.bestComparatorEver = new BestComparatorEver(comparators);
+ return this;
+ }
+
+ public SelectStmt having(Predicate condition) {
+ this.havingRestriction = condition;
+ return this;
+ }
+
+ public SelectStmt limit(int amount) {
+ maxRawsNeeded = amount;
+ return this;
+ }
+
+ public UnionStmt union() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
+ this.isUnion = true;
+ List answer = (List) this.execute();
+ System.out.println(answer.size());
+ if (isJoin) {
+ return new UnionStmt<>(answer, true);
+ } else {
+ return new UnionStmt<>(answer);
+ }
+ }
+
+
+}
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/Tuple.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/Tuple.java
new file mode 100644
index 0000000..dbc54a3
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/Tuple.java
@@ -0,0 +1,28 @@
+package ru.mipt.diht.students.simon23rus.CQL.impl;
+
+
+//F for first, S for second
+public class Tuple {
+ private final F first;
+ private final S second;
+
+ public Tuple(F first, S second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ public F getFirst() {
+ return first;
+ }
+ public S getSecond() {
+ return second;
+ }
+
+ @Override
+ public String toString() {
+ return "Tuple{"
+ + "first=" + first
+ + ", second=" + second
+ + "}";
+ }
+}
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/UnionStmt.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/UnionStmt.java
new file mode 100644
index 0000000..00cd9c2
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/impl/UnionStmt.java
@@ -0,0 +1,103 @@
+package ru.mipt.diht.students.simon23rus.CQL.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class UnionStmt {
+
+ private List oldQueries = new ArrayList<>();
+ private List currentQuery = new ArrayList<>();
+ private List> oldTupleElements = new ArrayList<>();
+ private boolean isTuple;
+ public UnionStmt(Iterable toIterate) {
+ toIterate.forEach(elem -> oldQueries.add(elem));
+ }
+ public UnionStmt(Iterable toIterate, boolean isTuple) {
+ toIterate.forEach(elem -> oldQueries.add(elem));
+ this.isTuple = true;
+ }
+
+ public UnionStmt(Iterable current, Iterable old) {
+ old.forEach(elem -> oldQueries.add(elem));
+ current.forEach(elem -> currentQuery.add(elem));
+ }
+
+ public FromMember from(Iterable elements) {
+ if (isTuple) {
+ return new FromMember(oldQueries, elements);
+ } else {
+ return new FromMember(oldQueries, elements);
+ }
+ }
+
+
+ public class FromMember {
+ public List getOldElements() {
+ return oldElements;
+ }
+ private List oldElements = new ArrayList<>();
+ private List currentElements = new ArrayList<>();
+
+ public List getCurrentElements() {
+ return currentElements;
+ }
+
+ public FromMember(Iterable pastElements, Iterable elements) {
+ pastElements.forEach(elem -> this.oldElements.add(elem));
+ elements.forEach(elem -> this.currentElements.add(elem));
+ }
+ @SafeVarargs
+ public final SelectStmt select(Class returnClass, Function... functions) {
+ return new SelectStmt((List) oldElements, currentElements, returnClass, false, functions);
+ }
+
+ public final SelectStmt> select(Function first, Function second) {
+ return new SelectStmt>((List>) oldElements, currentElements, false, first, second);
+ }
+
+ @SafeVarargs
+ public final SelectStmt selectDistinct(Class returnClass, Function... functions) {
+ return new SelectStmt((List) oldElements, currentElements, returnClass, true, functions);
+ }
+
+ public JoinMember join(Iterable iterable) {
+ return new JoinMember(oldElements, currentElements, iterable);
+ }
+ }
+
+ public class JoinMember {
+
+ private List firstElements = new ArrayList<>();
+ private List secondElements = new ArrayList<>();
+ private List oldElements = new ArrayList<>();
+ private List> currentElements = new ArrayList<>();
+
+ public JoinMember(List pastElements, List firstElements, Iterable secondElements) {
+ this.oldElements.addAll(pastElements.stream().collect(Collectors.toList()));
+ this.firstElements.addAll(firstElements.stream().collect(Collectors.toList()));
+ secondElements.forEach(elem -> this.secondElements.add(elem));
+ }
+
+ public FromMember, R> on(BiPredicate condition) {
+ firstElements.forEach(first ->
+ secondElements.forEach(second -> {
+ //esli udovletvoryaet predikatu, to ostavlyaem
+ if (condition.test(first, second)) {
+ this.currentElements.add(new Tuple<>(first, second));
+ }
+ }));
+ return new FromMember<>(oldElements, currentElements);
+ }
+
+ public > FromStmt> on(
+ Function leftKey,
+ Function rightKey) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
+
+
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/implOfAggregators/Aggregator.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/implOfAggregators/Aggregator.java
new file mode 100644
index 0000000..a37e469
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/implOfAggregators/Aggregator.java
@@ -0,0 +1,12 @@
+package ru.mipt.diht.students.simon23rus.CQL.implOfAggregators;
+
+
+import java.util.List;
+import java.util.function.Function;
+
+public interface Aggregator extends Function {
+ default C apply(List currentElements) {
+ return null;
+ }
+}
+
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/implOfAggregators/Avg.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/implOfAggregators/Avg.java
new file mode 100644
index 0000000..cbb9505
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/implOfAggregators/Avg.java
@@ -0,0 +1,31 @@
+package ru.mipt.diht.students.simon23rus.CQL.implOfAggregators;
+
+import java.util.List;
+import java.util.function.Function;
+
+
+public class Avg implements Aggregator {
+
+ private Function thisFunction;
+
+ public Avg(Function givenFunction) {
+ this.thisFunction = givenFunction;
+ }
+
+ @Override
+ public Double apply(List givenElements) {
+ Double result = 0.0;
+ for (T elem : givenElements) {
+ result += ((Double) thisFunction.apply(elem));
+ System.out.println(thisFunction.apply(elem));
+ }
+ return result / givenElements.size();
+ }
+
+ @Override
+ public Double apply(T toCheck) {
+ if(thisFunction.apply(toCheck) != null)
+ return ((Double) thisFunction.apply(toCheck));
+ return 0D;
+ }
+}
diff --git a/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/implOfAggregators/Count.java b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/implOfAggregators/Count.java
new file mode 100644
index 0000000..9beea63
--- /dev/null
+++ b/projects/simon23rus/src/main/java/ru/mipt/diht/students/simon23rus/CQL/implOfAggregators/Count.java
@@ -0,0 +1,36 @@
+package ru.mipt.diht.students.simon23rus.CQL.implOfAggregators;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Function;
+
+
+public class Count implements Aggregator {
+ private Function thisFunction;
+ public Count(Function givenFunction) {
+ this.thisFunction = givenFunction;
+ }
+
+ @Override
+ public Long apply(List givenElements) {
+ Set