From b38264b1aa894a01ecba12595c43372e2d1167a8 Mon Sep 17 00:00:00 2001 From: Drozdov Kirill Date: Sat, 19 Dec 2015 01:04:32 +0400 Subject: [PATCH 1/5] reverser --- .../students/drozdovkir/Reverser/Reverser.java | 10 ++++++++++ ... \320\257\321\200\320\273\321\213\320\272.lnk" | Bin 0 -> 701 bytes 2 files changed, 10 insertions(+) create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Reverser/Reverser.java create mode 100644 "somejavashit - \320\257\321\200\320\273\321\213\320\272.lnk" diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Reverser/Reverser.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Reverser/Reverser.java new file mode 100644 index 0000000..5bff759 --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Reverser/Reverser.java @@ -0,0 +1,10 @@ +public class Reverser { + public static void main(String[] args){ + for (int v = args.length - 1; v >= 0; v--){ + String[] currentString = args[v].split("//s"); + for (int r = currentString.length - 1; r >= 0; r--){ + System.out.print(currentString[r] + " "); + } + } + } +} diff --git "a/somejavashit - \320\257\321\200\320\273\321\213\320\272.lnk" "b/somejavashit - \320\257\321\200\320\273\321\213\320\272.lnk" new file mode 100644 index 0000000000000000000000000000000000000000..48fd37bebfee24b676df45d520a33848de6ca648 GIT binary patch literal 701 zcmah`O)ErU6n_A=Q-zn?{m(3p7+)R(8Otpfm4N1GlekdC_ifo*kgrr z&HTXC(ATKSsO}?qkF$t_-gejMPkS&rb*tB5$PvY*MC4nHoj;_!>_&mITW1Yz(?RyQ z`&^Pwk{wPjP(vdK2%OYegRT5Mo0K~lEN@Y2K1qfLZuG$g2|j`h2b`c5NG4RhM;?{e z>WM%lLk3l}ka zmpE;_N$~RtsVrb)$}K6z{+g84Ko@~-ccq;d^holEtY#_?7p3fOXyeV>j?uYY=eYi; Xed1t!@IK~b@y=9xXn+3iJ9l{lc6){w literal 0 HcmV?d00001 From ba6390be8603e49f1fec8f143e5a5ca67c4c784c Mon Sep 17 00:00:00 2001 From: Drozdov Kirill Date: Sat, 19 Dec 2015 13:18:21 +0400 Subject: [PATCH 2/5] please --- .../drozdovkir/Threads/Caller/Caller.java | 82 +++++++++++++++++++ .../drozdovkir/Threads/Caller/MainCl.java | 5 ++ .../drozdovkir/Threads/Counter/Counter.java | 39 +++++++++ .../drozdovkir/Threads/Counter/MainCn.java | 5 ++ .../drozdovkir/Threads/Queue/MainQ.java | 51 ++++++++++++ .../drozdovkir/Threads/Queue/QueueBlock.java | 34 ++++++++ 6 files changed, 216 insertions(+) create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Caller/Caller.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Caller/MainCl.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Counter/Counter.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Counter/MainCn.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Queue/MainQ.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Queue/QueueBlock.java diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Caller/Caller.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Caller/Caller.java new file mode 100644 index 0000000..23f1ed9 --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Caller/Caller.java @@ -0,0 +1,82 @@ +import java.util.Random; + +public class Caller { + private final Integer numberOfThreads; + private final Double LOW_PROBABILITY = 0.1; + private final long START = 3; + private Integer numberOfCalled = 0; + private Integer numberOfCalling = 0; + private boolean ready = false; + private Random random; + + class Callable implements Runnable { + private Integer called; + + Callable() { + called = 0; + numberOfCalled++; + } + + @Override + public void run() { + while (true) { + synchronized (Caller.this) { + while (called == numberOfCalling) { + if (numberOfCalled == numberOfThreads && ready) + return; + try { + Caller.this.wait(); + } catch (InterruptedException E) { + System.err.printf("Interrupted\n"); + return; + } + } + called++; + numberOfCalled++; + if (random.nextDouble() < LOW_PROBABILITY) { + System.out.printf("NO\n"); + ready = false; + } else { + System.out.printf("YES\n"); + } + Caller.this.notifyAll(); + } + } + } + } + + Caller(int number) { + numberOfThreads = number; + random = new Random(START); + main(); + } + + public void main() { + for (int i = 0; i < numberOfThreads; i++) { + new Thread(new Callable()).start(); + } + + while (true) { + synchronized (Caller.this) { + while (numberOfCalled != numberOfThreads) { + try { + Caller.this.wait(); + } catch (InterruptedException E) { + System.err.printf("Interrupted\n"); + return; + } + } + + if (ready) { + return; + } + + System.out.printf("Are you ready?\n"); + numberOfCalling++; + numberOfCalled = 0; + ready = true; + notifyAll(); + } + } + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Caller/MainCl.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Caller/MainCl.java new file mode 100644 index 0000000..bcf280d --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Caller/MainCl.java @@ -0,0 +1,5 @@ +public class MainCl { + public static void main(String[] args) { + new Caller(Integer.parseInt(args[1])); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Counter/Counter.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Counter/Counter.java new file mode 100644 index 0000000..ff1743e --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Counter/Counter.java @@ -0,0 +1,39 @@ +public class Counter { + private final Integer numberOfThreads; + private Integer currentThread; + + class Counted implements Runnable{ + private final Integer numberOfThread; + + Counted(Integer number) { + numberOfThread = number; + } + + @Override + public void run() { + while(true) { + synchronized (Counter.this) { + while ((currentThread + 1) % numberOfThreads != numberOfThread) { + try { + Counter.this.wait(); + } catch (InterruptedException E) { + System.err.printf("Interrutpted %d\n", numberOfThread); + return; + } + } + System.out.printf("Thread-%d\n", numberOfThread + 1); + currentThread = numberOfThread; + Counter.this.notifyAll(); + } + } + } + } + + Counter(Integer number) { + numberOfThreads = number; + currentThread = number - 1; + for (int i = 0; i < numberOfThreads; i++) { + new Thread(new Counted(i)).start(); + } + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Counter/MainCn.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Counter/MainCn.java new file mode 100644 index 0000000..17688cb --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Counter/MainCn.java @@ -0,0 +1,5 @@ +public class MainCn { + public static void main(String[] args) { + new Counter(Integer.parseInt(args[1])); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Queue/MainQ.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Queue/MainQ.java new file mode 100644 index 0000000..d78c511 --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Queue/MainQ.java @@ -0,0 +1,51 @@ +import java.util.ArrayList; +import java.util.List; + +public class MainQ { + private static QueueBlock queue = new QueueBlock<>(3); + + static class Put implements Runnable { + private List putting; + + Put(List list) { + putting = list; + } + + @Override + public void run() { + try { + queue.offer(putting); + } catch (InterruptedException e) { + System.err.printf("Interrupted\n"); + } + } + } + + static class Get implements Runnable { + private int n; + + Get(int number) { + n = number; + } + + @Override + public void run() { + try { + List result = queue.take(n); + for(int i = 0; i < n; i++) { + System.out.printf(String.valueOf(result.get(i))); + } + } catch (InterruptedException e) { + System.err.printf("Interrupted\n"); + } + } + } + + public static void main(String[] args) throws InterruptedException { + List list = new ArrayList(); + list.add(1); + list.add(2); + new Thread(new Put(list)).start(); + new Thread(new Get(1)).start(); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Queue/QueueBlock.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Queue/QueueBlock.java new file mode 100644 index 0000000..d502e1b --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/Threads/Queue/QueueBlock.java @@ -0,0 +1,34 @@ +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +public class QueueBlock { + private Queue queue; + private final Integer maxSize; + + QueueBlock(int number) { + maxSize = number; + queue = new LinkedList<>(); + } + + synchronized void offer(List list) throws InterruptedException { + while (queue.size() + list.size() > maxSize) { + wait(); + } + queue.addAll(list); + notifyAll(); + } + + synchronized List take(int n) throws InterruptedException { + while (queue.size() < n) { + wait(); + } + List result = new ArrayList(); + for (int i = 0; i < n; i++) { + result.add(queue.remove()); + } + notifyAll(); + return result; + } +} \ No newline at end of file From 46348e40fc72d28d3208d2f76a49bd62fcd065b0 Mon Sep 17 00:00:00 2001 From: Drozdov Kirill Date: Sat, 19 Dec 2015 13:58:13 +0400 Subject: [PATCH 3/5] MiniORM --- .../drozdovkir/MiniORM/DatabaseService.java | 145 ++++++++++++++++++ .../MiniORM/DatabaseServiceUtils.java | 137 +++++++++++++++++ .../MiniORM/StatementConstructor.java | 100 ++++++++++++ .../students/drozdovkir/MiniORM/TColumn.java | 49 ++++++ 4 files changed, 431 insertions(+) create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/DatabaseService.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/DatabaseServiceUtils.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/StatementConstructor.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/TColumn.java diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/DatabaseService.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/DatabaseService.java new file mode 100644 index 0000000..86f022c --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/DatabaseService.java @@ -0,0 +1,145 @@ +import javafx.util.Pair; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +public class DatabaseService { + static final String UNNAMED = ""; + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE) + public @interface Table { + String name() default UNNAMED; + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface Column { + String name() default UNNAMED; + + String type(); + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface PrimaryKey { + } + + private static final String DATABASE_PATH = "jdbc:h2:./simple_database"; + private StatementConstructor statementBuilder = null; + private String tableName = null; + private List columnList = null; + private TColumn primaryKey = null; + private Class itemsClass; + + public DatabaseService(Class newItemsClass) throws IllegalArgumentException { + itemsClass = newItemsClass; + tableName = DatabaseServiceUtils.getTableName(itemsClass); + Pair, TColumn> pair = DatabaseServiceUtils.analyseColumns(itemsClass); + columnList = pair.getKey(); + primaryKey = pair.getValue(); + statementBuilder = new StatementConstructor(tableName, columnList, + primaryKey, itemsClass); + } + + public final StatementConstructor getStatementBuilder() { + return statementBuilder; + } + + @FunctionalInterface + public interface CheckedFunction { + R apply(T t) throws SQLException, IllegalStateException; + } + + + private R databaseRequest(CheckedFunction action) { + try (Connection connection = DriverManager.getConnection(DATABASE_PATH)) { + Statement statement = connection.createStatement(); + return action.apply(statement); + } catch (SQLException e) { + throw new IllegalStateException("An SQL error occurred: " + e.getMessage()); + } + } + + public final void createTable() { + databaseRequest((Statement statement) -> { + statement.execute(statementBuilder.buildCreate()); + if (primaryKey != null) { + statement.execute("ALTER TABLE " + tableName + " ADD PRIMARY KEY (" + primaryKey.getName() + ")"); + System.err.println("PK успешно добавлен."); + } + return true; + }); + } + + public final void dropTable() { + databaseRequest((Statement statement) -> { + statement.execute("DROP TABLE IF EXISTS " + tableName); + return true; + }); + } + + public final void insert(T newItem) { + int added = databaseRequest( + (Statement statement) -> statement.executeUpdate(statementBuilder.buildInsert(newItem)) + ); + + if (added != 0) { + System.err.println("Элемент успешно добавлен."); + } + } + + public final List queryForAll() { + List allItems = databaseRequest((Statement statement) -> { + ResultSet resultSet = statement.executeQuery("SELECT * FROM " + tableName); + // Обрабатываем полученные результаты. + List selectAllList = new ArrayList<>(); + while (resultSet.next()) { + T item = DatabaseServiceUtils.createItemFromSqlResult(resultSet, columnList, itemsClass); + selectAllList.add(item); + } + return selectAllList; + }); + System.err.println("Get all items: " + allItems); + return allItems; + } + + public final T queryById(K key) { + T itemById = databaseRequest((Statement statement) -> { + ResultSet resultSet = statement.executeQuery("SELECT * FROM " + tableName + + " WHERE " + primaryKey.getName() + "=" + DatabaseServiceUtils.getSqlValue(key)); + + T item = null; + if (resultSet.next()) { + item = DatabaseServiceUtils.createItemFromSqlResult(resultSet, columnList, itemsClass); + } + if (resultSet.next()) { + throw new IllegalStateException("Primary key search result is not single"); + } + return item; + }); + System.err.println("Get item by ID: " + itemById); + return itemById; + } + + public final void update(T item) { + databaseRequest((Statement statement) -> { + statement.execute(statementBuilder.buildUpdate(item)); + return true; + }); + } + + public final void delete(K key) { + databaseRequest((Statement statement) -> { + statement.execute("DELETE FROM " + tableName + " WHERE " + + primaryKey.getName() + "=" + DatabaseServiceUtils.getSqlValue(key)); + return true; + }); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/DatabaseServiceUtils.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/DatabaseServiceUtils.java new file mode 100644 index 0000000..9c1f7d9 --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/DatabaseServiceUtils.java @@ -0,0 +1,137 @@ +import javafx.util.Pair; + +import ru.mipt.diht.students.drozdovkir.MiniORM.DatabaseService.Column; +import ru.mipt.diht.students.drozdovkir.MiniORM.DatabaseService.PrimaryKey; +import ru.mipt.diht.students.drozdovkir.MiniORM.DatabaseService.Table; + +import java.lang.reflect.Field; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Time; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; + + +import static java.lang.Character.isUpperCase; +import static java.lang.Character.toLowerCase; + +public class DatabaseServiceUtils { + public static String camelCaseToLowerCase(String text) { + StringBuilder lowerCaseText = new StringBuilder(""); + + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (isUpperCase(ch)) { + if (i != 0) { + lowerCaseText.append("_"); + } + lowerCaseText.append(toLowerCase(ch)); + } else { + lowerCaseText.append(ch); + } + } + return lowerCaseText.toString(); + } + + public static String getTableName(Class itemClass) throws IllegalArgumentException { + Table tableAnnotation; + if (itemClass.isAnnotationPresent(Table.class)) { + tableAnnotation = (Table) itemClass.getAnnotation(Table.class); + } else { + throw new IllegalArgumentException("Class has no @Table annotation"); + } + + String tableName = tableAnnotation.name(); + if (Objects.equals(tableName, DatabaseService.UNNAMED)) { + tableName = camelCaseToLowerCase(itemClass.getSimpleName()); + } + return tableName; + } + + public static Pair, TColumn> analyseColumns(Class itemClass) { + List columnList = new ArrayList<>(); + TColumn primaryKey = null; + + Field[] fields = itemClass.getDeclaredFields(); + for (Field field : fields) { + if (field.isAnnotationPresent(Column.class)) { + + Column column = field.getAnnotation(Column.class); + String name = column.name(); + String type = column.type(); + + + if (name.equals(DatabaseService.UNNAMED)) { + name = camelCaseToLowerCase(field.getName()); + } + TColumn itemColumn = new TColumn(name, type, field); + columnList.add(itemColumn); + + if (field.isAnnotationPresent(PrimaryKey.class)) { + if (primaryKey != null) { + throw new IllegalArgumentException("More than one primary key presents"); + } + primaryKey = itemColumn; + } + } + } + return new Pair, TColumn>(columnList, primaryKey); + } + + public static String getSqlValue(T object) { + if (object.getClass() == String.class || object.getClass() == char.class) { + return "\'" + object.toString() + "\'"; + } else { + return object.toString(); + } + } + + public static T createItemFromSqlResult(ResultSet resultSet, + List columnList, + Class itemClass) throws SQLException { + T newItem = null; + try { + newItem = (T) itemClass.newInstance(); + + for (TColumn column : columnList) { + Field field = column.getField(); + + + if (field.getType() == String.class || field.getType() == char.class) { + String value = resultSet.getString(column.getName()); + field.set(newItem, value); + } + + if (field.getType() == int.class || field.getType() == Integer.class) { + int value = resultSet.getInt(column.getName()); + field.set(newItem, value); + } + + if (field.getType() == float.class || field.getType() == Double.class) { + float value = resultSet.getFloat(column.getName()); + field.set(newItem, value); + } + // boolean + if (field.getType() == boolean.class) { + boolean value = resultSet.getBoolean(column.getName()); + field.set(newItem, value); + } + + if (field.getType() == Date.class) { + Date value = resultSet.getDate(column.getName()); + field.set(newItem, value); + } + + if (field.getType() == Time.class) { + Time value = resultSet.getTime(column.getName()); + field.set(newItem, value); + } + } + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + return newItem; + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/StatementConstructor.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/StatementConstructor.java new file mode 100644 index 0000000..6c9b054 --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/StatementConstructor.java @@ -0,0 +1,100 @@ +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import static java.util.stream.Collectors.joining; + +public class StatementConstructor { + private String tableName = null; + private List columnList = null; + private TColumn primaryKey = null; + private Class itemsClass; + + public StatementConstructor(String newTableName, + List newColumnList, + TColumn newPrimaryKey, + Class newItemsClass) { + this.tableName = newTableName; + this.columnList = newColumnList; + this.primaryKey = newPrimaryKey; + this.itemsClass = newItemsClass; + } + + public final String buildCreate() { + StringBuilder createQuery = new StringBuilder(); + createQuery.append("CREATE TABLE IF NOT EXISTS ") + .append(tableName) + .append(" ("); + + List columns = new ArrayList<>(); + for (TColumn column : columnList) { + StringBuilder columnsBuilder = new StringBuilder(); + columnsBuilder.append(column.getName()) + .append(" ") + .append(column.getType()); + if (column == primaryKey) { + columnsBuilder.append(" NOT NULL"); + } + columns.add(columnsBuilder.toString()); + } + + createQuery.append(columns.stream().collect(joining(", "))).append(")"); + return createQuery.toString(); + } + + public final String buildInsert(T newItem) { + StringBuilder insertQuery = new StringBuilder(); + insertQuery.append("INSERT INTO ") + .append(tableName) + .append(" VALUES ("); + + List columns = new ArrayList<>(); + for (TColumn column : columnList) { + Field field = column.getField(); + field.setAccessible(true); + + try { + columns.add(DatabaseServiceUtils.getSqlValue(field.get(newItem))); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + insertQuery.append(columns.stream().collect(joining(", "))).append(")"); + return insertQuery.toString(); + } + + public final String buildUpdate(T item) { + StringBuilder updateStatement = new StringBuilder(); + updateStatement.append("UPDATE ") + .append(tableName) + .append(" SET "); + + List columns = new ArrayList<>(); + for (TColumn column : columnList) { + StringBuilder columnBuilder = new StringBuilder(); + columnBuilder.append(column.getName()) + .append("="); + + Field field = column.getField(); + field.setAccessible(true); + try { + columnBuilder.append(DatabaseServiceUtils.getSqlValue(field.get(item))); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + columns.add(columnBuilder.toString()); + } + + updateStatement.append(columns.stream().collect(joining(", "))); + try { + updateStatement.append(" WHERE ") + .append(primaryKey.getName()) + .append("=") + .append(DatabaseServiceUtils.getSqlValue(primaryKey.getField().get(item))); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return updateStatement.toString(); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/TColumn.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/TColumn.java new file mode 100644 index 0000000..ebcfec1 --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/MiniORM/TColumn.java @@ -0,0 +1,49 @@ +import java.lang.reflect.Field; + +public class TColumn { + public TColumn(String newName, String newType, Field newField) { + this.name = newName; + this.type = newType; + this.field = newField; + } + + @Override + public final int hashCode() { + return 0; + } + + @Override + public final boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null) { + return false; + } + + if (getClass() != obj.getClass()) { + return false; + } + + TColumn other = (TColumn) obj; + return this.name.equals(other.name) + && this.type.equals(other.type); + } + + public final String getName() { + return name; + } + + public final String getType() { + return type; + } + + public final Field getField() { + return field; + } + + private String name; + private String type; + private Field field; +} \ No newline at end of file From 22392a019ad6777ac5729ce7d77b0daacdd545f8 Mon Sep 17 00:00:00 2001 From: Drozdov Kirill Date: Sat, 19 Dec 2015 14:32:56 +0400 Subject: [PATCH 4/5] CQL --- .../students/drozdovkir/CQL/Aggregates.java | 109 ++++++++++ .../students/drozdovkir/CQL/Conditions.java | 14 ++ .../CQL/EmptyCollectionException.java | 5 + .../students/drozdovkir/CQL/FromStmt.java | 201 ++++++++++++++++++ .../drozdovkir/CQL/OrderByConditions.java | 13 ++ .../diht/students/drozdovkir/CQL/Query.java | 6 + .../drozdovkir/CQL/QueryExecuteException.java | 5 + .../students/drozdovkir/CQL/SelectStmt.java | 92 ++++++++ .../diht/students/drozdovkir/CQL/Sources.java | 43 ++++ .../diht/students/drozdovkir/CQL/Tuple.java | 26 +++ .../CQL/UnequalUnionClassesException.java | 5 + .../students/drozdovkir/CQL/UnionStmt.java | 11 + .../students/drozdovkir/CQL/WhereStmt.java | 183 ++++++++++++++++ 13 files changed, 713 insertions(+) create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Aggregates.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Conditions.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/EmptyCollectionException.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/FromStmt.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/OrderByConditions.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Query.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/QueryExecuteException.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/SelectStmt.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Sources.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Tuple.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/UnequalUnionClassesException.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/UnionStmt.java create mode 100644 projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/WhereStmt.java diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Aggregates.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Aggregates.java new file mode 100644 index 0000000..2016a9e --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Aggregates.java @@ -0,0 +1,109 @@ +import ru.fizteh.fivt.students.drozdovkir.collectionquery.EmptyCollectionException; + +import java.util.Collection; +import java.util.Collections; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class Aggregates { + + public interface Agregator extends Function { + T apply(Collection collection) throws EmptyCollectionException; + } + + public static > Agregator max(Function expression) { + return new Agregator() { + @Override + public T apply(Collection collection) throws EmptyCollectionException { + if (collection.isEmpty()) { + throw new EmptyCollectionException("Method max was called for empty collection."); + } + return Collections.max(collection.stream().map(expression).collect(Collectors.toList())); + } + + @Override + public T apply(C c) { + return expression.apply(c); + } + }; + } + + + public static > Agregator min(Function expression) { + return new Agregator() { + @Override + public T apply(Collection collection) throws EmptyCollectionException { + if (collection.isEmpty()) { + throw new EmptyCollectionException("Method min was called for empty collection."); + } + return Collections.min(collection.stream().map(expression).collect(Collectors.toList())); + } + + @Override + public T apply(C c) { + return expression.apply(c); + } + }; + } + + + public static > Agregator count(Function expression) { + return new Agregator() { + @Override + public Long apply(Collection collection) { + if (collection.isEmpty()) { + return 0L; + } + return collection.stream().map(expression).count(); + } + + @Override + public Long apply(C c) { + if (expression.apply(c) != null) { + return 1L; + } + return 0L; + } + }; + } + + + public static Agregator avg(Function expression) { + return new Agregator() { + @Override + public T apply(Collection collection) throws EmptyCollectionException { + if (collection.isEmpty()) { + throw new EmptyCollectionException("Method avg was called for empty collection."); + } + T example = expression.apply(collection.iterator().next()); + if (example instanceof Integer) { + int sum = 0; + for (C elem : collection) { + sum += (Integer) expression.apply(elem); + } + return (T) Integer.valueOf(sum / collection.size()); + } + if (example instanceof Long) { + int sum = 0; + for (C elem : collection) { + sum += (Long) expression.apply(elem); + } + return (T) Long.valueOf(sum / collection.size()); + } + if (example instanceof Double || example instanceof Float) { + double sum = 0; + for (C elem : collection) { + sum += (Long) expression.apply(elem); + } + return (T) Double.valueOf(sum / collection.size()); + } + throw new ClassCastException("Class type is not detected!"); + } + + @Override + public T apply(C c) { + return expression.apply(c); + } + }; + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Conditions.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Conditions.java new file mode 100644 index 0000000..44074ec --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Conditions.java @@ -0,0 +1,14 @@ +import java.util.function.Function; +import java.util.function.Predicate; + +public class Conditions { + + + public static Predicate rlike(Function expression, String regexp) { + return element -> expression.apply(element).matches(regexp); + } + + public static Predicate like(Function expression, String pattern) { + throw new UnsupportedOperationException(); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/EmptyCollectionException.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/EmptyCollectionException.java new file mode 100644 index 0000000..25d8420 --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/EmptyCollectionException.java @@ -0,0 +1,5 @@ +public class EmptyCollectionException extends Exception { + public EmptyCollectionException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/FromStmt.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/FromStmt.java new file mode 100644 index 0000000..985a77d --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/FromStmt.java @@ -0,0 +1,201 @@ +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 Iterable previousQuery; + private Iterable data; + + FromStmt(Iterable iterable) { + this.data = iterable; + } + + FromStmt(Iterable iterable, Iterable previous) { + data = iterable; + previousQuery = previous; + } + + private FromStmt(Stream stream) { + data = stream.collect(Collectors.toList()); + } + + public static FromStmt from(Iterable iterable) { + return new FromStmt<>(iterable); + } + + public static FromStmt from(Stream stream) { + return new FromStmt<>(stream); + } + + public static FromStmt from(Query query) throws QueryExecuteException, EmptyCollectionException { + return new FromStmt<>(query.execute()); + } + + @SafeVarargs + public final SelectStmt select(Class clazz, Function... s) throws UnequalUnionClassesException { + try { + return new SelectStmt<>((Iterable) previousQuery, data, clazz, false, s); + } catch (ClassCastException ex) { + try { + List newIterable = new ArrayList<>(); + previousQuery.forEach(el -> newIterable.add((R) el)); + return new SelectStmt<>(newIterable, data, clazz, false, s); + } catch (ClassCastException exeption) { + throw new UnequalUnionClassesException("Uncasted classes can't be union.", ex); + } + } + } + + public final SelectStmt select(Function s) throws UnequalUnionClassesException { + try { + return new SelectStmt<>((Iterable) previousQuery, data, false, s); + } catch (ClassCastException ex) { + try { + List newIterable = new ArrayList<>(); + previousQuery.forEach(el -> newIterable.add((R) el)); + return new SelectStmt<>(newIterable, data, false, s); + } catch (ClassCastException exception) { + throw new UnequalUnionClassesException("Uncasted classes can't be union.", ex); + } + } + } + + public final SelectStmt> select(Function first, Function second) + throws UnequalUnionClassesException { + try { + return new SelectStmt<>((Iterable>) previousQuery, data, false, first, second); + } catch (ClassCastException ex) { + try { + List> newIterable = new ArrayList<>(); + previousQuery.forEach(el -> newIterable.add((Tuple) el)); + return new SelectStmt<>(newIterable, data, false, first, second); + } catch (ClassCastException exception) { + throw new UnequalUnionClassesException("Uncasted classes can't be union.", ex); + } + } + } + + @SafeVarargs + public final SelectStmt selectDistinct(Class clazz, Function... s) + throws UnequalUnionClassesException { + try { + return new SelectStmt<>((Iterable) previousQuery, data, clazz, true, s); + } catch (ClassCastException ex) { + try { + List newIterable = new ArrayList<>(); + previousQuery.forEach(el -> newIterable.add((R) el)); + return new SelectStmt<>(newIterable, data, clazz, false, s); + } catch (ClassCastException exception) { + throw new UnequalUnionClassesException("Uncasted classes can't be union.", ex); + } + } + } + + + public final SelectStmt selectDistinct(Function s) throws UnequalUnionClassesException { + try { + return new SelectStmt<>((Iterable) previousQuery, data, false, s); + } catch (ClassCastException ex) { + try { + List newIterable = new ArrayList<>(); + previousQuery.forEach(el -> newIterable.add((R) el)); + return new SelectStmt<>(newIterable, data, false, s); + } catch (ClassCastException exception) { + throw new UnequalUnionClassesException("Uncasted classes can't be union.", ex); + } + } + } + + public final SelectStmt> selectDistinct(Function first, Function second) + throws UnequalUnionClassesException { + try { + return new SelectStmt<>((Iterable>) previousQuery, data, false, first, second); + } catch (ClassCastException ex) { + try { + List> newIterable = new ArrayList<>(); + previousQuery.forEach(el -> newIterable.add((Tuple) el)); + return new SelectStmt<>(newIterable, data, false, first, second); + } catch (ClassCastException exception) { + throw new UnequalUnionClassesException("Uncasted classes can't be union.", ex); + } + } + } + + public final JoinClause join(Iterable iterable) { + return new JoinClause<>(data, iterable); + } + + public final JoinClause join(Stream stream) { + return new JoinClause<>(data, stream.collect(Collectors.toList())); + } + + public final JoinClause join(Query stream) throws QueryExecuteException, EmptyCollectionException { + return new JoinClause<>(data, stream.execute()); + } + + public class JoinClause { + private Iterable first; + private Iterable second; + + JoinClause(Iterable fst, Iterable snd) { + this.first = fst; + this.second = snd; + } + + public final FromStmt> on(BiPredicate condition) { + List list = new LinkedList<>(); + first.forEach(list::add); + + List> result = new ArrayList<>(); + second.forEach(element -> { + for (int i = 0; i < list.size(); i++) { + if (condition.test(list.get(i), element)) { + result.add(new Tuple<>(list.get(i), element)); + list.remove(i); + break; + } + } + }); + + return new FromStmt<>(result); + } + + public final > FromStmt> on( + Function leftKey, + Function rightKey) { + + Map> mapOfT = new HashMap<>(); + first.forEach(elem -> { + K key = leftKey.apply(elem); + if (!mapOfT.containsKey(key)) { + List inserted = new LinkedList<>(); + inserted.add(elem); + mapOfT.put(key, inserted); + } else { + List inserted = mapOfT.get(key); + inserted.add(elem); + mapOfT.put(key, inserted); + } + }); + + List> result = new ArrayList<>(); + second.forEach((elem) -> { + K key = rightKey.apply(elem); + if (mapOfT.containsKey(key)) { + List replaced = mapOfT.get(key); + result.add(new Tuple<>(replaced.get(0), elem)); + replaced.remove(0); + if (replaced.isEmpty()) { + mapOfT.remove(key); + } else { + mapOfT.put(key, replaced); + } + } + }); + + return new FromStmt<>(result); + } + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/OrderByConditions.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/OrderByConditions.java new file mode 100644 index 0000000..a20a485 --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/OrderByConditions.java @@ -0,0 +1,13 @@ +import java.util.Comparator; +import java.util.function.Function; + +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)); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Query.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Query.java new file mode 100644 index 0000000..079544e --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Query.java @@ -0,0 +1,6 @@ +import java.util.stream.Stream; + +public interface Query { + Iterable execute() throws QueryExecuteException, EmptyCollectionException; + Stream stream() throws QueryExecuteException, EmptyCollectionException; +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/QueryExecuteException.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/QueryExecuteException.java new file mode 100644 index 0000000..498620e --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/QueryExecuteException.java @@ -0,0 +1,5 @@ +public class QueryExecuteException extends Exception { + QueryExecuteException(String message, Throwable reason) { + super(message, reason); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/SelectStmt.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/SelectStmt.java new file mode 100644 index 0000000..7a91b8d --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/SelectStmt.java @@ -0,0 +1,92 @@ +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class SelectStmt implements Query { + private Iterable data; + private Iterable previous; + private Function[] functions; + private Class returnedClass; + private boolean isDistinct; + private boolean isTupleR; + + @SafeVarargs + SelectStmt(Iterable prvious, Iterable dta, Class clazz, boolean isDistnct, Function... s) { + this.data = dta; + this.previous = prvious; + functions = s; + returnedClass = clazz; + this.isDistinct = isDistnct; + isTupleR = false; + } + + SelectStmt(Iterable prvious, Iterable dta, boolean isDistnct, Function func) { + this.data = dta; + this.previous = prvious; + functions = new Function[]{func}; + returnedClass = (Class) func.apply(data.iterator().next()).getClass(); + this.isDistinct = isDistnct; + isTupleR = false; + } + + SelectStmt(Iterable prvious, Iterable dta, boolean isDistnct, + Function first, Function second) { + this.data = dta; + this.previous = prvious; + functions = new Function[]{first, second}; + returnedClass = (Class) (new Tuple(first.apply(data.iterator().next()), + second.apply(data.iterator().next()))).getClass(); + this.isDistinct = isDistnct; + isTupleR = true; + } + + public final WhereStmt where(Predicate predicate) { + return new WhereStmt<>(previous, data, returnedClass, predicate, isDistinct, isTupleR, functions); + } + + @Override + public final Iterable execute() throws QueryExecuteException { + if (data == null) { + return new ArrayList<>(); + } + + Object[] constructorArguments = new Object[functions.length]; + Class[] resultClasses = new Class[functions.length]; + for (int i = 0; i < functions.length; i++) { + resultClasses[i] = functions[i].apply(data.iterator().next()).getClass(); + } + + ArrayList result = new ArrayList<>(); + for (T element : data) { + for (int i = 0; i < functions.length; i++) { + constructorArguments[i] = functions[i].apply(element); + } + try { + if (isTupleR) { + result.add((R) new Tuple(constructorArguments[0], constructorArguments[1])); + } else { + result.add(returnedClass.getConstructor(resultClasses).newInstance(constructorArguments)); + } + } catch (Exception ex) { + throw new QueryExecuteException("Failed to construct output class!", ex); + } + } + + if (previous != null) { + previous.forEach(result::add); + } + + if (isDistinct) { + return result.stream().distinct().collect(Collectors.toList()); + } + return result; + } + + @Override + public final Stream stream() throws QueryExecuteException { + return StreamSupport.stream(execute().spliterator(), false); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Sources.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Sources.java new file mode 100644 index 0000000..94aeb60 --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Sources.java @@ -0,0 +1,43 @@ +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.util.*; +import java.util.stream.Stream; + +public class Sources { + + @SafeVarargs + public static List list(T... items) { + return Arrays.asList(items); + } + + + @SafeVarargs + public static Set set(T... items) { + return new HashSet<>(Arrays.asList(items)); + } + + + public static Stream lines(InputStream inputStream) throws IOException, ClassCastException { + final int bufferSize = 1000; + StringBuilder builder = new StringBuilder(); + byte[] data = new byte[bufferSize]; + Stream.Builder stream = Stream.builder(); + + while (inputStream.read(data) > 0) { + builder.append(data); + } + String[] lines = builder.toString().split("[\n]"); + //предполагается что каждый элемент на отдельной строке + for (String line : lines) { + stream.add((T) line); + } + return stream.build(); + } + + + public static Stream lines(Path file) throws IOException, ClassCastException { + return lines(new FileInputStream(file.toFile())); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Tuple.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Tuple.java new file mode 100644 index 0000000..328236b --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Tuple.java @@ -0,0 +1,26 @@ +public class Tuple { + + private final F first; + private final S second; + + public Tuple(F fst, S snd) { + this.first = fst; + this.second = snd; + } + + public final F getFirst() { + return first; + } + + public final S getSecond() { + return second; + } + + @Override + public final String toString() { + return "Tuple{" + + "first=" + first + + ", second=" + second + + '}'; + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/UnequalUnionClassesException.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/UnequalUnionClassesException.java new file mode 100644 index 0000000..0405580 --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/UnequalUnionClassesException.java @@ -0,0 +1,5 @@ +public class UnequalUnionClassesException extends Exception { + UnequalUnionClassesException(String message, Throwable reason) { + super(message, reason); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/UnionStmt.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/UnionStmt.java new file mode 100644 index 0000000..51b4ffa --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/UnionStmt.java @@ -0,0 +1,11 @@ +public class UnionStmt { + private Iterable previous; + + UnionStmt(Iterable iterable) { + previous = iterable; + } + + public final FromStmt from(Iterable list) { + return new FromStmt<>(list, previous); + } +} \ No newline at end of file diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/WhereStmt.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/WhereStmt.java new file mode 100644 index 0000000..169d979 --- /dev/null +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/WhereStmt.java @@ -0,0 +1,183 @@ +import javafx.util.Pair; +import ru.fizteh.fivt.students.drozdovkir.collectionquery.Aggregates; + +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class WhereStmt implements Query { + private Stream stream; + private Iterable previous; + private Function[] convertFunctions; + private Class returnedClass; + private Function>[] groupingFunctions; + private Predicate groupingCondition; + private Comparator resultComparator; + private T example; //for initialization of out output class constructor arguments + private boolean isDistinct; + private boolean isTupleR; + private long maxResultSize = -1; + + private Object[] constructorArguments; + private Class[] resultClasses; + + WhereStmt(Iterable prev, Iterable iterable, Class clazz, Predicate predicate, + boolean isDistnct, boolean isTuplR, Function[] convFunctions) { + stream = StreamSupport.stream(iterable.spliterator(), false).filter(predicate); + returnedClass = clazz; + this.previous = prev; + this.convertFunctions = convFunctions; + this.isDistinct = isDistnct; + this.isTupleR = isTuplR; + groupingCondition = null; + if (iterable.iterator().hasNext()) { + example = iterable.iterator().next(); + } else { + example = null; + } + } + + @SafeVarargs + public final WhereStmt groupBy(Function>... expressions) { + groupingFunctions = expressions; + return this; + } + + @SafeVarargs + public final WhereStmt orderBy(Comparator... comparators) { + resultComparator = getCombinedComparator(Arrays.asList(comparators)); + return this; + } + + public final WhereStmt having(Predicate condition) { + groupingCondition = condition; + return this; + } + + public final WhereStmt limit(int amount) { + maxResultSize = amount; + return this; + } + + public final UnionStmt union() throws UnequalUnionClassesException, + QueryExecuteException, EmptyCollectionException { + return new UnionStmt<>(this.execute()); + } + + @Override + public final Iterable execute() throws QueryExecuteException, EmptyCollectionException { + return this.stream().collect(Collectors.toList()); + } + + @Override + public final Stream stream() throws QueryExecuteException, EmptyCollectionException { + constructorArguments = new Object[convertFunctions.length]; + resultClasses = new Class[convertFunctions.length]; + + if (example == null) { + return (new ArrayList()).stream(); + } + + for (int i = 0; i < convertFunctions.length; i++) { + resultClasses[i] = convertFunctions[i].apply(example).getClass(); + } + + ArrayList result = new ArrayList<>(); + if (groupingFunctions != null) { + Map mapped = new HashMap<>(); + List> groupedElements = new ArrayList<>(); + List> grouped = new ArrayList<>(); + String[] results = new String[groupingFunctions.length]; + stream.forEach( + element -> { + for (int i = 0; i < groupingFunctions.length; i++) { + results[i] = (String) groupingFunctions[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)))); + } + ); + + 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) { + for (int i = 0; i < convertFunctions.length; i++) { + if (convertFunctions[i] instanceof Aggregates.Agregator) { + constructorArguments[i] = ((Aggregates.Agregator) convertFunctions[i]).apply(group); + } else { + constructorArguments[i] = convertFunctions[i].apply(group.get(0)); + } + resultClasses[i] = constructorArguments[i].getClass(); + } + try { + if (isTupleR) { + result.add((R) new Tuple<>(constructorArguments[0], constructorArguments[1])); + } else { + result.add(returnedClass.getConstructor(resultClasses) + .newInstance(constructorArguments)); + } + } catch (Exception ex) { + throw new QueryExecuteException("Failed to construct output class!", ex); + } + } + } else { + if (resultComparator != null) { + stream.sorted(resultComparator); + } + for (T element : stream.collect(Collectors.toList())) { + addToList(result, element); + } + } + + if (previous != null) { + previous.forEach(result::add); + } + + Stream finalResult; + if (isDistinct) { + finalResult = result.stream().distinct(); + } else { + finalResult = result.stream(); + } + if (maxResultSize != -1) { + finalResult = finalResult.limit(maxResultSize); + } + if (groupingCondition != null) { + finalResult = finalResult.filter(groupingCondition); + } + return finalResult; + } + + private void addToList(List list, T element) throws QueryExecuteException { + for (int i = 0; i < convertFunctions.length; i++) { + constructorArguments[i] = convertFunctions[i].apply(element); + } + try { + list.add(returnedClass.getConstructor(resultClasses).newInstance(constructorArguments)); + } catch (Exception ex) { + throw new QueryExecuteException("Failed to construct output class!", ex); + } + } + + private static Comparator getCombinedComparator(List> comparators) { + return (o1, o2) -> { + for (Comparator comp : comparators) { + int res = comp.compare(o1, o2); + if (res != 0) { + return res; + } + } + return 0; + }; + } +} \ No newline at end of file From fb65a268011ffdf5946422bb3b090c5ccbb06d7d Mon Sep 17 00:00:00 2001 From: Drozdov Kirill Date: Sat, 19 Dec 2015 14:38:39 +0400 Subject: [PATCH 5/5] CQL v.2 --- .../java/ru/mipt/diht/students/drozdovkir/CQL/Aggregates.java | 2 +- .../java/ru/mipt/diht/students/drozdovkir/CQL/WhereStmt.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Aggregates.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Aggregates.java index 2016a9e..e0cf037 100644 --- a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Aggregates.java +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/Aggregates.java @@ -1,4 +1,4 @@ -import ru.fizteh.fivt.students.drozdovkir.collectionquery.EmptyCollectionException; +import ru.mipt.diht.students.drozdovkir.CQL.EmptyCollectionException; import java.util.Collection; import java.util.Collections; diff --git a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/WhereStmt.java b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/WhereStmt.java index 169d979..48001ef 100644 --- a/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/WhereStmt.java +++ b/projects/drozdovkir/src/main/java/ru/mipt/diht/students/drozdovkir/CQL/WhereStmt.java @@ -1,5 +1,5 @@ import javafx.util.Pair; -import ru.fizteh.fivt.students.drozdovkir.collectionquery.Aggregates; +import ru.mipt.diht.students.drozdovkir.CQL.Aggregates; import java.util.*; import java.util.function.Function;