diff --git a/ocksumoron/pom.xml b/ocksumoron/pom.xml index 9dab73c7..67ca2171 100644 --- a/ocksumoron/pom.xml +++ b/ocksumoron/pom.xml @@ -19,7 +19,7 @@ junit junit - 3.8.1 + 4.12 test @@ -38,5 +38,15 @@ jsoup 1.8.3 + + com.google.guava + guava + 18.0 + + + com.h2database + h2 + 1.4.190 + diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/Aggregates.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/Aggregates.java new file mode 100644 index 00000000..2297a6cf --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/Aggregates.java @@ -0,0 +1,63 @@ +package ru.fizteh.fivt.students.ocksumoron.collectionquery; + + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Function; + +public class Aggregates { + public static Function count(Function expression) { + return new Count<>(expression); + } + + public static Function avg(Function expression) { + return new Avg<>(expression); + } + + public interface Aggregator extends Function { + C apply(List list); + } + + public static class Count implements Aggregator { + + private Function function; + public Count(Function expression) { + this.function = expression; + } + + @Override + public Integer apply(List list) { + Set distinctedList = new HashSet<>(); + list.stream().filter(e -> !distinctedList.contains(function.apply(e))).forEach(e -> { + distinctedList.add(function.apply(e)); + }); + return distinctedList.size(); + } + @Override + public Integer apply(T t) { + return null; + } + } + + public static class Avg implements Aggregator { + private Function function; + public Avg(Function expression) { + this.function = expression; + } + + @Override + public Double apply(List list) { + Double result = 0.0; + for (T e : list) { + result += function.apply(e).floatValue(); + } + return result / list.size(); + } + + @Override + public Double apply(T t) { + return null; + } + } +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/Conditions.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/Conditions.java new file mode 100644 index 00000000..59f01404 --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/Conditions.java @@ -0,0 +1,10 @@ +package ru.fizteh.fivt.students.ocksumoron.collectionquery; + +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); + } +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/OrderByConditions.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/OrderByConditions.java new file mode 100644 index 00000000..65f1ddbb --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/OrderByConditions.java @@ -0,0 +1,32 @@ +package ru.fizteh.fivt.students.ocksumoron.collectionquery; + +import java.util.Comparator; +import java.util.function.Function; + +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/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/Sources.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/Sources.java new file mode 100644 index 00000000..786f5649 --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/Sources.java @@ -0,0 +1,19 @@ +package ru.fizteh.fivt.students.ocksumoron.collectionquery; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Sources { + + /** + * @param items + * @param + * @return + */ + @SafeVarargs + public static List list(T... items) { + return new ArrayList<>(Arrays.asList(items)); + } + +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/FromStmt.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/FromStmt.java new file mode 100644 index 00000000..c6b0a740 --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/FromStmt.java @@ -0,0 +1,82 @@ +package ru.fizteh.fivt.students.ocksumoron.collectionquery.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class FromStmt { + private List list = new ArrayList(); + + public FromStmt(Iterable iterable) { + for (T curr : iterable) { + list.add(curr); + } + } + + public static FromStmt from(Iterable iterable) { + return new FromStmt<>(iterable); + } + + @SafeVarargs + public final SelectStmt select(Class clazz, Function... functions) { + return new SelectStmt<>(list, clazz, false, functions); + } + + @SafeVarargs + public final SelectStmt selectDistinct(Class clazz, Function... functions) { + return new SelectStmt<>(list, clazz, true, functions); + } + + public final SelectStmt> select(Function first, Function second) { + return new SelectStmt<>(list, false, first, second); + } + + public JoinClause join(Iterable iterable) { + return new JoinClause(list, iterable); + } + + public class JoinClause { + private List firstList = new ArrayList<>(); + private List secondList = new ArrayList<>(); + private List> list = new ArrayList<>(); + + public JoinClause(List firstList, Iterable secondList) { + this.firstList.addAll(firstList.stream().collect(Collectors.toList())); + for (J curr : secondList) { + this.secondList.add(curr); + } + } + + public FromStmt> on(BiPredicate condition) { + for (S first : firstList) { + list.addAll(secondList.stream().filter(second -> condition.test(first, second)) + .map(second -> new Tuple<>(first, second)).collect(Collectors.toList())); + } + return new FromStmt<>(list); + } + + public > FromStmt> on( + Function leftKey, + Function rightKey) { + HashMap> map = new HashMap<>(); + for (J e : secondList) { + K key = rightKey.apply(e); + if (!map.containsKey(key)) { + map.put(key, new ArrayList<>()); + } + map.get(key).add(e); + } + for (S first : firstList) { + K key = leftKey.apply(first); + if (map.containsKey(key)) { + List second = map.get(key); + second.forEach(s -> list.add(new Tuple<>(first, s))); + } + } + return new FromStmt<>(list); + } + } +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/Query.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/Query.java new file mode 100644 index 00000000..c419f1dd --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/Query.java @@ -0,0 +1,8 @@ +package ru.fizteh.fivt.students.ocksumoron.collectionquery.impl; + +import java.lang.reflect.InvocationTargetException; + +public interface Query { + Iterable execute() throws NoSuchMethodException, + IllegalAccessException, InvocationTargetException, InstantiationException; +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/SelectStmt.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/SelectStmt.java new file mode 100644 index 00000000..3ff3d947 --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/SelectStmt.java @@ -0,0 +1,221 @@ +package ru.fizteh.fivt.students.ocksumoron.collectionquery.impl; + +import javafx.util.Pair; +import ru.fizteh.fivt.students.ocksumoron.collectionquery.Aggregates; + +import java.lang.reflect.InvocationTargetException; +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class SelectStmt implements Query { + private boolean isDistinct; + private Class clazz; + private Function[] functions; + private List list; + private List pastList; + private Predicate wherePredicate; + private Comparator[] orderByComparators; + private Predicate havingPredicate; + private int limit; + private Function[] groupByFunctions; + private CQLComparator cqlComparator; + private boolean isUnion; + private boolean isJoin; + + private void init(List list, Class clazz, boolean isDistinct, Function[] functions, + boolean isUnion, boolean isJoin, List pastList) { + this.list = new ArrayList<>(); + this.list.addAll(list.stream().collect(Collectors.toList())); + this.clazz = clazz; + this.isDistinct = isDistinct; + this.functions = functions; + this.limit = -1; + this.isUnion = isUnion; + this.isJoin = isJoin; + this.pastList = pastList; + } + + @SafeVarargs + public SelectStmt(List list, Class clazz, boolean isDistinct, Function... functions) { + init(list, clazz, isDistinct, functions, false, false, null); + } + + public SelectStmt(List list, boolean isDistinct, Function first, Function second) { + init(list, list.get(0).getClass(), isDistinct, new Function[]{first, second}, false, true, null); + } + + @SafeVarargs + public SelectStmt(List pastList, List list, Class clazz, boolean isDistinct, Function... functions) { + init(list, clazz, isDistinct, functions, true, false, pastList); + } + + public SelectStmt(List pastList, List list, boolean isDistinct, Function first, Function second) { + init(list, list.get(0).getClass(), isDistinct, new Function[]{first, second}, true, true, pastList); + } + + public SelectStmt where(Predicate predicate) { + this.wherePredicate = predicate; + return this; + } + + @SafeVarargs + public final SelectStmt groupBy(Function... functions) { + this.groupByFunctions = functions; + return this; + } + + @SafeVarargs + public final SelectStmt orderBy(Comparator... orderByComparators) { + this.orderByComparators = orderByComparators; + this.cqlComparator = new CQLComparator(orderByComparators); + return this; + } + + public SelectStmt having(Predicate predicate) { + this.havingPredicate = predicate; + return this; + } + + public SelectStmt limit(int amount) { + this.limit = amount; + return this; + } + + public Iterable execute() throws NoSuchMethodException, IllegalAccessException, + InvocationTargetException, InstantiationException { + List result = new ArrayList<>(); + Object[] arguments = new Object[functions.length]; + Class[] clazzes = new Class[functions.length]; + if (wherePredicate != null) { + List filtered = new ArrayList<>(); + list.stream().filter(wherePredicate::test).forEach(filtered::add); + list = filtered; + } + if (groupByFunctions != null) { + Map mapped = new HashMap<>(); + String[] results = new String[groupByFunctions.length]; + List> groupped = new ArrayList<>(); + list.stream().forEach( + element -> { + for (int i = 0; i < groupByFunctions.length; i++) { + results[i] = (String) groupByFunctions[i].apply(element); + } + if (!mapped.containsKey(Objects.hash(results))) { + mapped.put(Objects.hash(results), mapped.size()); + } + groupped.add(new Pair(element, mapped.get(Objects.hash(results)))); + } + ); + List> grouppedList = new ArrayList<>(); + for (int i = 0; i < mapped.size(); i++) { + grouppedList.add(new ArrayList()); + } + + for (Pair element : groupped) { + grouppedList.get(element.getValue()).add(element.getKey()); + } + for (List group : grouppedList) { + for (int i = 0; i < functions.length; i++) { + if (functions[i] instanceof Aggregates.Aggregator) { + arguments[i] = ((Aggregates.Aggregator) functions[i]).apply(group); + } else { + arguments[i] = functions[i].apply(group.get(0)); + } + clazzes[i] = arguments[i].getClass(); + } + if (isJoin) { + Tuple newElement = new Tuple(arguments[0], arguments[1]); + result.add((R) newElement); + } else { + R newElement = (R) clazz.getConstructor(clazzes).newInstance(arguments); + result.add(newElement); + } + } + } else { + for (T element : this.list) { + for (int i = 0; i < functions.length; i++) { + arguments[i] = functions[i].apply(element); + if (functions[i] instanceof Aggregates.Aggregator) { + List currArg = new ArrayList<>(); + currArg.add(element); + arguments[i] = ((Aggregates.Aggregator) functions[i]).apply(currArg); + } else { + arguments[i] = functions[i].apply(element); + } + clazzes[i] = arguments[i].getClass(); + } + if (isJoin) { + Tuple newElement = new Tuple(arguments[0], arguments[1]); + result.add((R) newElement); + } else { + R newElement = (R) clazz.getConstructor(clazzes).newInstance(arguments); + result.add(newElement); + } + } + } + if (havingPredicate != null) { + List filtered = new ArrayList<>(); + result.stream().filter(havingPredicate::test).forEach(filtered::add); + result = filtered; + } + if (isDistinct) { + Set hashes = new HashSet<>(); + List flags = new ArrayList<>(); + for (R element : result) { + if (!hashes.contains(element.toString().hashCode())) { + flags.add(1); + hashes.add(element.toString().hashCode()); + } else { + flags.add(0); + } + } + List distincted = new ArrayList<>(); + for (int i = 0; i < result.size(); i++) { + if (flags.get(i) == 1) { + distincted.add(result.get(i)); + } + } + result = distincted; + } + if (orderByComparators != null) { + result.sort(cqlComparator); + } + if (limit != -1) { + while (result.size() > limit) { + result.remove(result.size() - 1); + } + } + if (isUnion) { + pastList.addAll(result); + result = pastList; + } + return result; + } + + public UnionStmt union() throws InvocationTargetException, NoSuchMethodException, + InstantiationException, IllegalAccessException { + List result = (List) this.execute(); + return new UnionStmt<>(result); + } + + public class CQLComparator implements Comparator { + private Comparator[] orderByComparators; + @SafeVarargs + public CQLComparator(Comparator... orderByComparators) { + this.orderByComparators = orderByComparators; + } + + @Override + public int compare(K first, K second) { + for (Comparator comparator : orderByComparators) { + if (comparator.compare(first, second) != 0) { + return comparator.compare(first, second); + } + } + return 0; + } + } + +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/Tuple.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/Tuple.java new file mode 100644 index 00000000..bd48a771 --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/Tuple.java @@ -0,0 +1,28 @@ +package ru.fizteh.fivt.students.ocksumoron.collectionquery.impl; + +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/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/UnionStmt.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/UnionStmt.java new file mode 100644 index 00000000..8b9c82ed --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/impl/UnionStmt.java @@ -0,0 +1,101 @@ +package ru.fizteh.fivt.students.ocksumoron.collectionquery.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class UnionStmt { + private List pastList = new ArrayList<>(); + + public UnionStmt(Iterable iterable) { + for (R curr : iterable) { + pastList.add(curr); + } + } + + public FromClause from(Iterable list) { + return new FromClause(pastList, list); + } + + public class FromClause { + private List pastList = new ArrayList<>(); + private List list = new ArrayList<>(); + + public FromClause(Iterable pastList, Iterable list) { + for (R curr : pastList) { + this.pastList.add(curr); + } + for (S curr : list) { + this.list.add(curr); + } + } + @SafeVarargs + public final SelectStmt select(Class clazz, Function... functions) { + return new SelectStmt((List) pastList, list, clazz, false, functions); + } + + public final SelectStmt> select(Function first, Function second) { + return new SelectStmt>((List>) pastList, list, false, first, second); + } + + @SafeVarargs + public final SelectStmt selectDistinct(Class clazz, Function... functions) { + return new SelectStmt((List) pastList, list, clazz, true, functions); + } + + public JoinClause join(Iterable iterable) { + return new JoinClause(pastList, list, iterable); + } + } + + public class JoinClause { + + private List firstList = new ArrayList<>(); + private List secondList = new ArrayList<>(); + private List pastList = new ArrayList<>(); + private List> list = new ArrayList<>(); + + public JoinClause(List pastList, List firstList, Iterable secondList) { + this.pastList.addAll(pastList.stream().collect(Collectors.toList())); + this.firstList.addAll(firstList.stream().collect(Collectors.toList())); + for (J curr : secondList) { + this.secondList.add(curr); + } + } + + public FromClause, R> on(BiPredicate condition) { + for (F first : firstList) { + for (J second : secondList) { + if (condition.test(first, second)) { + list.add(new Tuple<>(first, second)); + } + } + } + return new FromClause<>(pastList, list); + } + + public > FromClause, R> on( + Function leftKey, + Function rightKey) { + HashMap> map = new HashMap<>(); + for (J e : secondList) { + K key = rightKey.apply(e); + if (!map.containsKey(key)) { + map.put(key, new ArrayList<>()); + } + map.get(key).add(e); + } + for (F first : firstList) { + K key = leftKey.apply(first); + if (map.containsKey(key)) { + List second = map.get(key); + second.forEach(s -> list.add(new Tuple<>(first, s))); + } + } + return new FromClause<>(pastList, list); + } + } +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/Column.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/Column.java new file mode 100644 index 00000000..8893e300 --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/Column.java @@ -0,0 +1,9 @@ +package ru.fizteh.fivt.students.ocksumoron.miniorm; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Column { + String name() default ""; +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/DatabaseService.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/DatabaseService.java new file mode 100644 index 00000000..ae0e8115 --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/DatabaseService.java @@ -0,0 +1,272 @@ +package ru.fizteh.fivt.students.ocksumoron.miniorm; + +import com.google.common.base.CaseFormat; +import org.h2.jdbcx.JdbcConnectionPool; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.sql.*; +import java.util.*; + +public class DatabaseService implements Closeable { + private final String connectionName; + private final String username; + + private final String password; + + private Class clazz; + + private JdbcConnectionPool pool; + + private String tableName; + private Field[] fields; + private int pkIndex = -1; + + static String convert(String name) { + if ('a' <= name.charAt(0) && name.charAt(0) <= 'z') { + return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, name); + } + return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, name); + } + + String getColumnName(Field f) { + String name = f.getAnnotation(Column.class).name(); + if (name.isEmpty()) { + return convert(f.getName()); + } + return name; + } + + void init() throws IllegalArgumentException, IOException { + if (!clazz.isAnnotationPresent(Table.class)) { + throw new IllegalArgumentException("no @Table annotation"); + } + + tableName = clazz.getAnnotation(Table.class).name(); + if (tableName.isEmpty()) { + tableName = convert(clazz.getSimpleName()); + } + + Set names = new HashSet<>(); + List fieldsList = new ArrayList<>(); + for (Field f: clazz.getDeclaredFields()) { + if (f.isAnnotationPresent(Column.class)) { + String name = getColumnName(f); + names.add(name); + f.setAccessible(true); + fieldsList.add(f); + if (f.isAnnotationPresent(PrimaryKey.class)) { + if (pkIndex == -1) { + pkIndex = fieldsList.size() - 1; + } else { + throw new + IllegalArgumentException("Several @PrimaryKey"); + } + } + } else if (f.isAnnotationPresent(PrimaryKey.class)) { + throw new + IllegalArgumentException("@PrimaryKey without @Column"); + } + } + + if (names.size() != fieldsList.size()) { + throw new IllegalArgumentException("Duplicate columns"); + } + + fields = new Field[fieldsList.size()]; + fields = fieldsList.toArray(fields); + + try { + Class.forName("org.h2.Driver"); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("No H2 driver found"); + } + + pool = JdbcConnectionPool.create(connectionName, username, password); + } + + DatabaseService(Class newClazz, String properties) throws IOException { + Properties credits = new Properties(); + try (InputStream inputStream + = this.getClass().getResourceAsStream(properties)) { + credits.load(inputStream); + } + connectionName = credits.getProperty("connection_name"); + username = credits.getProperty("username"); + password = credits.getProperty("password"); + + clazz = newClazz; + init(); + } + + DatabaseService(Class newClazz) throws IOException { + this(newClazz, "/h2test.properties"); + } + + void createTable() throws SQLException { + StringBuilder queryBuilder = new StringBuilder("CREATE TABLE IF NOT EXISTS " + tableName + "("); + for (int i = 0; i < fields.length; ++i) { + if (i != 0) { + queryBuilder.append(", "); + } + queryBuilder.append(getColumnName(fields[i]) + " " + H2StringsResolver.resolve(fields[i].getType())); + if (i == pkIndex) { + queryBuilder.append(" PRIMARY KEY"); + } + } + queryBuilder.append(")"); + try (Connection conn = pool.getConnection()) { + conn.createStatement().execute(queryBuilder.toString()); + } + + } + + void dropTable() throws SQLException { + StringBuilder queryBuilder = new StringBuilder(); + queryBuilder.append("DROP TABLE IF EXISTS ") + .append(tableName); + try (Connection conn = pool.getConnection()) { + conn.createStatement().execute(queryBuilder.toString()); + } + } + + public void insert(T record) throws SQLException, IllegalAccessException { + StringBuilder queryBuilder = new StringBuilder("INSERT INTO ").append(tableName).append(" ("); + for (int i = 0; i < fields.length; ++i) { + if (i != 0) { + queryBuilder.append(", "); + } + queryBuilder.append(getColumnName(fields[i]) + " "); + } + queryBuilder.append(") VALUES ("); + for (int i = 0; i < fields.length; ++i) { + if (i != 0) { + queryBuilder.append(", "); + } + queryBuilder.append("?"); + } + queryBuilder.append(")"); + + + try (Connection conn = pool.getConnection()) { + PreparedStatement statement + = conn.prepareStatement(queryBuilder.toString()); + for (int i = 0; i < fields.length; ++i) { + statement.setObject(i + 1, fields[i].get(record)); + } + statement.execute(); + } + } + + public void delete(T record) throws IllegalArgumentException, + IllegalAccessException, SQLException { + if (pkIndex == -1) { + throw new IllegalArgumentException("NO @PrimaryKey"); + } + StringBuilder queryBuilder = new StringBuilder(); + queryBuilder.append("DELETE FROM " + tableName + " WHERE " + fields[pkIndex].getName() + " = ?"); + + try (Connection conn = pool.getConnection()) { + PreparedStatement statement + = conn.prepareStatement(queryBuilder.toString()); + statement.setObject(1, fields[pkIndex].get(record)); + statement.execute(); + } + } + + public void update(T record) throws IllegalArgumentException, + SQLException, IllegalAccessException { + if (pkIndex == -1) { + throw new IllegalArgumentException("NO @PrimaryKey"); + } + + StringBuilder queryBuilder = new StringBuilder("UPDATE " + tableName + " SET "); + for (int i = 0; i < fields.length; ++i) { + if (i != 0) { + queryBuilder.append(", "); + } + queryBuilder.append(getColumnName(fields[i]) + " = ?"); + } + queryBuilder.append(" WHERE " + getColumnName(fields[pkIndex]) + " = ?"); + + try (Connection conn = pool.getConnection()) { + PreparedStatement statement + = conn.prepareStatement(queryBuilder.toString()); + for (int i = 0; i < fields.length; ++i) { + statement.setObject(i + 1, fields[i].get(record)); + } + statement.setObject(fields.length + 1, fields[pkIndex].get(record)); + statement.execute(); + } + } + + public T queryById(K key) throws IllegalArgumentException, + SQLException { + StringBuilder queryBuilder = new StringBuilder(); + queryBuilder.append("SELECT * FROM " + tableName + " WHERE " + fields[pkIndex].getName() + " = ?"); + try (Connection conn = pool.getConnection()) { + PreparedStatement statement = conn.prepareStatement(queryBuilder.toString()); + statement.setString(1, key.toString()); + try (ResultSet rs = statement.executeQuery()) { + rs.next(); + T record = clazz.newInstance(); + for (int i = 0; i < fields.length; ++i) { + if (fields[i].getClass().isAssignableFrom(Number.class)) { + Long val = rs.getLong(i + 1); + fields[i].set(record, val); + } else if (fields[i].getType() != String.class) { + fields[i].set(record, rs.getObject(i + 1)); + } else { + Clob data = rs.getClob(i + 1); + fields[i].set(record, data.getSubString(1, (int) data.length())); + } + } + return record; + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalArgumentException("wrong class"); + } + } + + } + + public List queryForAll() throws SQLException { + List result = new ArrayList<>(); + + StringBuilder queryBuilder = new StringBuilder(); + queryBuilder.append("SELECT * FROM " + tableName); + + try (Connection conn = pool.getConnection()) { + try (ResultSet rs = conn.createStatement() + .executeQuery(queryBuilder.toString())) { + while (rs.next()) { + T record = clazz.newInstance(); + for (int i = 0; i < fields.length; ++i) { + if (fields[i].getClass().isAssignableFrom(Number.class)) { + Long val = rs.getLong(i + 1); + fields[i].set(record, val); + } else if (fields[i].getType() != String.class) { + fields[i].set(record, rs.getObject(i + 1)); + } else { + Clob data = rs.getClob(i + 1); + fields[i].set(record, data.getSubString(1, (int) data.length())); + } + } + result.add(record); + } + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalArgumentException("wrong class"); + } + } + return result; + } + + + + @Override + public void close() throws IOException { + if (pool != null) { + pool.dispose(); + } + } +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/H2StringsResolver.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/H2StringsResolver.java new file mode 100644 index 00000000..0bef3e03 --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/H2StringsResolver.java @@ -0,0 +1,38 @@ +package ru.fizteh.fivt.students.ocksumoron.miniorm; + +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +class H2StringsResolver { + private static Map h2Strings; + static { + h2Strings = new HashMap<>(); + h2Strings.put(Integer.class, "INTEGER"); + h2Strings.put(Boolean.class, "BOOLEAN"); + h2Strings.put(Byte.class, "TINYINT"); + h2Strings.put(Short.class, "SMALLINT"); + h2Strings.put(Long.class, "BIGINT"); + h2Strings.put(Double.class, "DOUBLE"); + h2Strings.put(Float.class, "FLOAT"); + h2Strings.put(Time.class, "TIME"); + h2Strings.put(Date.class, "DATE"); + h2Strings.put(Timestamp.class, "TIMESTAMP"); + h2Strings.put(Character.class, "CHAR"); + h2Strings.put(String.class, "CLOB"); + h2Strings.put(UUID.class, "UUID"); + } + + public static String resolve(Class clazz) { + if (h2Strings.containsKey(clazz)) { + return h2Strings.get(clazz); + } + if (clazz.isArray()) { + return "ARRAY"; + } + return "OTHER"; + } +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/PrimaryKey.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/PrimaryKey.java new file mode 100644 index 00000000..7e7d576b --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/PrimaryKey.java @@ -0,0 +1,9 @@ +package ru.fizteh.fivt.students.ocksumoron.miniorm; + + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface PrimaryKey { +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/Table.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/Table.java new file mode 100644 index 00000000..89ae1357 --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/miniorm/Table.java @@ -0,0 +1,10 @@ +package ru.fizteh.fivt.students.ocksumoron.miniorm; + + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Table { + String name() default ""; +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/moduletests/TwisterImpl.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/moduletests/TwisterImpl.java new file mode 100644 index 00000000..4d4a0f01 --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/moduletests/TwisterImpl.java @@ -0,0 +1,9 @@ +package ru.fizteh.fivt.students.ocksumoron.moduletests; + +/** + * Created by ocksumoron on 05.10.15. + */ +//public class TwisterImpl implements TwisterService { +// @Override +// List +//} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/moduletests/TwisterService.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/moduletests/TwisterService.java new file mode 100644 index 00000000..531de180 --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/moduletests/TwisterService.java @@ -0,0 +1,14 @@ +package ru.fizteh.fivt.students.ocksumoron.moduletests; + +import ru.fizteh.fivt.students.ocksumoron.twitterstream.JCommanderProperties; + +import java.util.List; + +/** + * Created by ocksumoron on 05.10.15. + */ +public interface TwisterService { + List printTweets(JCommanderProperties jcp); + + void printStream(JCommanderProperties jcp); +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/Counter.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/Counter.java new file mode 100644 index 00000000..1be05c6e --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/Counter.java @@ -0,0 +1,52 @@ +package ru.fizteh.fivt.students.ocksumoron.threads; + +/** + * Created by ocksumoron on 14.12.15. + */ +public class Counter { + + private static volatile int currentID; + + private static Object synchronizer = new Object(); + + private static class OneCounter implements Runnable { + private int id, size; + + + OneCounter(int id, int size) { + this.id = id; + this.size = size; + } + + @Override + public void run() { + while (true) { + try { + synchronized (synchronizer) { + while (id != currentID) { + synchronizer.wait(); + } + System.out.println("Thread-" + String.valueOf(id)); + currentID++; + if (currentID > size) { + currentID %= size; + } + synchronizer.notifyAll(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + public static void main(String[] args) { + int n; + n = Integer.valueOf(args[0]); + currentID = 1; + for (int i = 0; i < n; i++) { + Thread oneCounter = new Thread(new OneCounter(i + 1, n)); + oneCounter.start(); + } + } +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/RollCall.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/RollCall.java new file mode 100644 index 00000000..891773dc --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/RollCall.java @@ -0,0 +1,81 @@ +package ru.fizteh.fivt.students.ocksumoron.threads; + +import java.util.Random; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +/** + * Created by ocksumoron on 14.12.15. + */ +public class RollCall { + + private static volatile boolean allReady; + private static boolean finish; + private static volatile Random chance = new Random(); + private static CyclicBarrier beginAnswer; + private static CyclicBarrier endAnswer; + private static final int NO_PROBABILITY = 10; + + private static class Player extends Thread { + + @Override + public void run() { + while (!finish) { + try { + beginAnswer.await(); + } catch (InterruptedException | BrokenBarrierException e) { + e.printStackTrace(); + } + if (chance.nextInt(100) > NO_PROBABILITY) { + System.out.println("Yes"); + } else { + System.out.println("No"); + allReady = false; + } + try { + endAnswer.await(); + } catch (InterruptedException | BrokenBarrierException e) { + e.printStackTrace(); + } + } + } + + + } + + public static void main(String[] args) { + finish = false; + + int n = Integer.valueOf(args[0]); + beginAnswer = new CyclicBarrier(n + 1); + endAnswer = new CyclicBarrier(n + 1); + Player[] players = new Player[n]; + for (int i = 0; i < n; i++) { + players[i] = new Player(); + players[i].start(); + } + finish = false; + while (!finish) { + System.out.println("Are you ready?"); + allReady = true; + try { + beginAnswer.await(); + } catch (BrokenBarrierException | InterruptedException e) { + e.printStackTrace(); + } + beginAnswer.reset(); + try { + endAnswer.await(); + if (allReady) { + finish = true; + for (int i = 0; i < n; i++) { + players[i].join(); + } + System.exit(0); + } + } catch (BrokenBarrierException | InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/blockingqueue/BlockingQueue.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/blockingqueue/BlockingQueue.java new file mode 100644 index 00000000..028eb72b --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/blockingqueue/BlockingQueue.java @@ -0,0 +1,108 @@ +package ru.fizteh.fivt.students.ocksumoron.threads.blockingqueue; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by ocksumoron on 16.12.15. + */ +public class BlockingQueue { + + private Queue queue; + private int maxSize; + private final Lock lock = new ReentrantLock(); + private final Condition notEnoughSpace = lock.newCondition(); + private final Condition notEnoughElements = lock.newCondition(); + private final Object offerSynchronizer = new Object(); + private final Object takeSynchronizer = new Object(); + + BlockingQueue(int size) { + queue = new ArrayDeque(); + maxSize = size; + } + + void offer(List toAdd) throws InterruptedException { + synchronized (offerSynchronizer) { + lock.lock(); + try { + while ((queue.size() + toAdd.size()) > maxSize) { + notEnoughSpace.await(); + } + queue.addAll(toAdd); + notEnoughElements.signalAll(); + } finally { + lock.unlock(); + } + } + } + + List take(int n) throws InterruptedException { + synchronized (takeSynchronizer) { + lock.lock(); + List ans = new ArrayList(); + try { + + while (queue.size() < n) { + notEnoughElements.await(); + } + for (int i = 0; i < n; ++i) { + ans.add(queue.remove()); + } + notEnoughElements.signalAll(); + } finally { + lock.unlock(); + return ans; + } + } + } + + void offer(List toAdd, long timeout) throws InterruptedException { + synchronized (offerSynchronizer) { + lock.lock(); + long waitingTime = timeout; + final long startTime = System.currentTimeMillis(); + try { + while (queue.size() + toAdd.size() > maxSize && waitingTime > 0) { + notEnoughElements.await(waitingTime, TimeUnit.MILLISECONDS); + waitingTime = timeout - (System.currentTimeMillis() - startTime); + } + if (queue.size() + toAdd.size() <= maxSize) { + queue.addAll(toAdd); + notEnoughElements.notifyAll(); + } + } finally { + lock.unlock(); + } + } + } + + List take(int n, long timeout) throws InterruptedException { + synchronized (takeSynchronizer) { + lock.lock(); + List ans = new ArrayList(); + long waitingTime = timeout; + final long startTime = System.currentTimeMillis(); + try { + while (queue.size() < n && waitingTime > 0) { + notEnoughElements.await(waitingTime, TimeUnit.MILLISECONDS); + waitingTime = timeout - (System.currentTimeMillis() - startTime); + } + if (queue.size() >= n) { + for (int i = 0; i < n; ++i) { + ans.add(queue.remove()); + } + notEnoughElements.notifyAll(); + } + } finally { + lock.unlock(); + return ans; + } + } + } +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/blockingqueue/Main.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/blockingqueue/Main.java new file mode 100644 index 00000000..188f9c6b --- /dev/null +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/threads/blockingqueue/Main.java @@ -0,0 +1,8 @@ +package ru.fizteh.fivt.students.ocksumoron.threads.blockingqueue; + +/** + * Created by ocksumoron on 17.12.15. + */ +public class Main { + +} diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/FormatMaster.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/FormatMaster.java index 78705449..29cba653 100644 --- a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/FormatMaster.java +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/FormatMaster.java @@ -96,7 +96,7 @@ public static String format(Status s, boolean isHideRetweets, boolean isStream) + s.getRetweetedStatus().getUser().getName() + ": " + s.getRetweetedStatus().getText()); } else { result.append("@" + s.getUser().getName() + ": " + s.getText()); - if (s.getRetweetCount() != 0) { + if (s.isRetweeted()) { result.append(" (" + Long.toString(s.getRetweetCount()) + " " + RETWEET_FORMS[getCorrectForm(s.getRetweetCount()).getType()] + ")"); } diff --git a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/Twister.java b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/Twister.java index bfbeaf73..4d0bbe7c 100644 --- a/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/Twister.java +++ b/ocksumoron/src/main/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/Twister.java @@ -25,7 +25,8 @@ public static void main(String[] args) { } } catch (Exception e) { e.printStackTrace(); - new JCommander(jcp).usage(); + JCommander jc = new JCommander(jcp); + jc.addCommand(args); } } diff --git a/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/CollectionQueryTest.java b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/CollectionQueryTest.java new file mode 100644 index 00000000..1bf1ee7b --- /dev/null +++ b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/collectionquery/CollectionQueryTest.java @@ -0,0 +1,191 @@ +package ru.fizteh.fivt.students.ocksumoron.collectionquery; + +import ru.fizteh.fivt.students.ocksumoron.collectionquery.impl.Tuple; + +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.fizteh.fivt.students.ocksumoron.collectionquery.Aggregates.avg; +import static ru.fizteh.fivt.students.ocksumoron.collectionquery.Aggregates.count; +import static ru.fizteh.fivt.students.ocksumoron.collectionquery.CollectionQueryTest.Student.student; +import static ru.fizteh.fivt.students.ocksumoron.collectionquery.Conditions.rlike; +import static ru.fizteh.fivt.students.ocksumoron.collectionquery.OrderByConditions.asc; +import static ru.fizteh.fivt.students.ocksumoron.collectionquery.OrderByConditions.desc; +import static ru.fizteh.fivt.students.ocksumoron.collectionquery.Sources.list; +import static ru.fizteh.fivt.students.ocksumoron.collectionquery.impl.FromStmt.from; + +import org.junit.Assert; +import org.junit.Test; + + +public class CollectionQueryTest { + + @Test + public void test1() throws InvocationTargetException, + NoSuchMethodException, InstantiationException, IllegalAccessException { + Iterable statistics = + from(list( + student("ivanov", LocalDate.parse("1986-08-06"), "494"), + student("sidorov", LocalDate.parse("1986-08-06"), "495"), + student("smith", LocalDate.parse("1986-08-06"), "495"), + student("petrov", LocalDate.parse("2006-08-06"), "494"))) + .select(Statistics.class, Student::getGroup, count(Student::getGroup), avg(Student::age)) + .where(rlike(Student::getName, ".*ov").and(s -> s.age() > 20)) + .groupBy(Student::getGroup) + .having(s -> s.getCount() > 0) + .orderBy(asc(Statistics::getGroup), desc(Statistics::getCount)) + .limit(100) + .union() + .from(list(student("ivanov", LocalDate.parse("1985-08-06"), "494"))) + .selectDistinct(Statistics.class, s->"all", count(s -> 1), avg(Student::age)) + .execute(); + Iterable> mentorsByStudent = + from(list(student("ivanov", LocalDate.parse("1985-08-06"), "494"))) + .join(list(new Group("494", "mr.sidorov"))) + .on((s, g) -> Objects.equals(s.getGroup(), g.getGroup())) + .select(sg -> sg.getFirst().getName(), sg -> sg.getSecond().getMentor()) + .execute(); + Assert.assertEquals(statistics.toString(), + "[Statistics{group='494', count=1, age=29.0}\n" + + ", Statistics{group='495', count=1, age=29.0}\n" + + ", Statistics{group='all', count=1, age=30.0}\n" + + "]"); + Assert.assertEquals(mentorsByStudent.toString(), + "[Tuple{first=ivanov, second=mr.sidorov}" + + "]"); + } + + public static class Student { + private final String name; + + private final LocalDate dateOfBirth; + + private final String group; + + public String getName() { + return name; + } + + public Student(String name, LocalDate dateOfBirth, String group) { + this.name = name; + this.dateOfBirth = dateOfBirth; + this.group = group; + } + + 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 dateOfBirth, String group) { + return new Student(name, dateOfBirth, group); + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder().append("Student{"); + if (group != null) { + result.append("group='").append(group).append('\''); + } + if (name != null) { + result.append(", name=").append(name); + } + if (dateOfBirth != null) { + result.append(", age=").append(dateOfBirth); + } + result.append("}\n"); + return result.toString(); + } + } + + 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 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(); + } + } + + public static class Statistics { + + private final String group; + private final Integer count; + private final Double age; + + public String getGroup() { + return group; + } + + public Integer getCount() { + return count; + } + + public Statistics(String group) { + this.group = group; + this.count = null; + this.age = null; + } + + public Statistics(String group, Integer count) { + this.group = group; + this.count = count; + this.age = null; + } + + public Statistics(String group, Integer count, Double age) { + this.group = group; + this.count = count; + this.age = age; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder().append("Statistics{"); + if (group != null) { + result.append("group='").append(group).append('\''); + } + if (count != null) { + result.append(", count=").append(count); + } + if (age != null) { + result.append(", age=").append(age); + } + result.append("}\n"); + return result.toString(); + } + } +} \ No newline at end of file diff --git a/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/miniorm/DatabaseServiceTest.java b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/miniorm/DatabaseServiceTest.java new file mode 100644 index 00000000..e3fdce6a --- /dev/null +++ b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/miniorm/DatabaseServiceTest.java @@ -0,0 +1,184 @@ +package ru.fizteh.fivt.students.ocksumoron.miniorm; + +import org.h2.jdbcx.JdbcConnectionPool; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.sql.Connection; +import java.sql.ResultSet; +import java.util.Properties; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.*; +import static ru.fizteh.fivt.students.ocksumoron.miniorm.DatabaseService.convert; + + +public class DatabaseServiceTest { + + @Test(expected = IllegalArgumentException.class) + public void testIllegalClass_1() throws Exception { + class X { + @Column + int y; + } + new DatabaseService(X.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalClass_2() throws Exception { + @Table + class X { + @Column + int y; + + @Column(name = "y") + String x; + } + new DatabaseService(X.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalClass_3_0() throws Exception { + @Table + class X { + @Column + int y; + } + DatabaseService x = new DatabaseService<>(X.class); + x.delete(new X()); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalClass_3_1() throws Exception { + @Table + class X { + @Column + int y; + } + DatabaseService x = new DatabaseService<>(X.class); + x.update(new X()); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalClass_4() throws Exception { + @Table + class X { + @PrimaryKey + @Column + int y; + + + @PrimaryKey + String x; + } + new DatabaseService(X.class); + } + + @Test + public void convertTest() throws Exception { + assertThat(convert("camelCase"), is("camel_case")); + assertThat(convert("CamelCase"), is("camel_case")); + } + + + private static final String CONNECTION_NAME; + private static final String USERNAME; + private static final String PASSWORD; + + static { + Properties credits = new Properties(); + try (InputStream inputStream + = DatabaseServiceTest.class + .getResourceAsStream("/h2test.properties")) { + credits.load(inputStream); + } catch (IOException e) { + e.printStackTrace(); + } + CONNECTION_NAME = credits.getProperty("connection_name"); + USERNAME = credits.getProperty("username"); + PASSWORD = credits.getProperty("password"); + } + + @Table + static class MyClass { + @PrimaryKey + @Column + Integer x; + + @Column + String y; + + MyClass() { + } + + MyClass(Integer x, String y) { + this.x = x; + this.y = y; + } + + @Override + public boolean equals(Object o) { + if (o instanceof MyClass) { + MyClass omc = (MyClass) o; + return x.equals(omc.x) && y.equals(omc.y); + } + return false; + } + } + + @Test + public void bigTest() throws Exception { + + + DatabaseService x = new DatabaseService<>(MyClass.class, + "/h2test.properties"); + JdbcConnectionPool pool = JdbcConnectionPool + .create(CONNECTION_NAME, USERNAME, PASSWORD); + Connection tmp; + tmp = pool.getConnection(); + tmp.createStatement() + .execute("DROP TABLE IF EXISTS my_class"); + tmp.close(); + + x.createTable(); + tmp = pool.getConnection(); + tmp.createStatement() + .execute("INSERT INTO my_class (x, y) VALUES (1, 'one')"); + tmp.close(); + assertThat(x.queryById(1).y, is("one")); + x.insert(new MyClass(2, "X")); + x.insert(new MyClass(3, "X")); + tmp = pool.getConnection(); + ResultSet rs = tmp.createStatement() + .executeQuery("SELECT * FROM my_class WHERE y = 'X'"); + int count = 0; + int sum = 0; + while(rs.next()) { + assertThat(rs.getInt(1), anyOf(is(2), is(3))); + ++count; + sum += rs.getInt(1); + } + + rs.close(); + tmp.close(); + + assertThat(count, is(2)); + assertThat(sum, is(5)); + + assertThat(x.queryForAll().size(), is(3)); + assertThat(x.queryForAll(), hasItem(new MyClass(1, "one"))); + x.update(new MyClass(1, "two")); + assertThat(x.queryForAll(), not(hasItem(new MyClass(1, "one")))); + assertThat(x.queryForAll(), hasItem(new MyClass(1, "two"))); + x.delete(new MyClass(1, "")); + assertThat(x.queryForAll(), not(hasItem(new MyClass(1, "two")))); + + + x.dropTable(); + x.close(); + } +} \ No newline at end of file diff --git a/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/threads/blockingqueue/BlockingQueueTest.java b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/threads/blockingqueue/BlockingQueueTest.java new file mode 100644 index 00000000..b61dfb54 --- /dev/null +++ b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/threads/blockingqueue/BlockingQueueTest.java @@ -0,0 +1,93 @@ +package ru.fizteh.fivt.students.ocksumoron.threads.blockingqueue; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.*; + +public class BlockingQueueTest { + + @Test + public void testWithThreads() throws InterruptedException { + BlockingQueue queue = new BlockingQueue(100); + TakeThread thread1 = new TakeThread(1, 10, 2, queue); + PutThread thread2 = new PutThread(10, 1, 1, queue); + thread1.start(); + thread2.start(); + try { + thread1.join(); + thread2.join(); + } catch (InterruptedException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + } + + private static class PutThread extends Thread { + private int amount, range; + private double sleepInterval; + private BlockingQueue queue; + PutThread(int range, int amount, double sleepInterval, BlockingQueue queue) { + this.range = range; + this.amount = amount; + this.sleepInterval = sleepInterval; + this.queue = queue; + } + + @Override + public void run() { + int currentToPut = 0; + for (int i = 0; i < amount; i++) { + try { + sleep((int)sleepInterval); + } catch (InterruptedException e) { + e.printStackTrace(); + } + try { + ArrayList list = new ArrayList(range); + for (int j = 0; j < range; ++j) { + list.add(currentToPut++); + } + queue.offer(list); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + private static class TakeThread extends Thread { + private int amount, range; + private double sleepInterval; + private BlockingQueue queue; + TakeThread(int range, int amount, double sleepInterval, BlockingQueue queue) { + this.range = range; + this.amount = amount; + this.sleepInterval = sleepInterval; + this.queue = queue; + } + + @Override + public void run() { + Integer last = 0; + int currentToTake = 0; + for (int i = 0; i < amount; ++i) { + try { + sleep((int)(sleepInterval)); + } catch (InterruptedException e) { + System.err.println(e.getMessage()); + } + try { + List list = queue.take(range); + List goodList = new ArrayList<>(); + for (int j = 0; j < range; ++j) { + goodList.add(currentToTake++); + } + Assert.assertEquals(list, goodList); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } +} \ No newline at end of file diff --git a/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/FormatMasterTest.java b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/FormatMasterTest.java new file mode 100644 index 00000000..8492ffd6 --- /dev/null +++ b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/FormatMasterTest.java @@ -0,0 +1,10 @@ +package ru.fizteh.fivt.students.ocksumoron.twitterstream; + +import static org.junit.Assert.*; + +/** + * Created by ocksumoron on 18.12.15. + */ +public class FormatMasterTest { + +} \ No newline at end of file diff --git a/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/LocationMasterTest.java b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/LocationMasterTest.java new file mode 100644 index 00000000..22baf946 --- /dev/null +++ b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/LocationMasterTest.java @@ -0,0 +1,10 @@ +package ru.fizteh.fivt.students.ocksumoron.twitterstream; + +import static org.junit.Assert.*; + +/** + * Created by ocksumoron on 18.12.15. + */ +public class LocationMasterTest { + +} \ No newline at end of file diff --git a/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/TwisterTest.java b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/TwisterTest.java new file mode 100644 index 00000000..3acc4c46 --- /dev/null +++ b/ocksumoron/src/test/java/ru/fizteh/fivt/students/ocksumoron/twitterstream/TwisterTest.java @@ -0,0 +1,10 @@ +package ru.fizteh.fivt.students.ocksumoron.twitterstream; + +import static org.junit.Assert.*; + +/** + * Created by ocksumoron on 18.12.15. + */ +public class TwisterTest { + +} \ No newline at end of file diff --git a/pom.xml.orig b/pom.xml.orig new file mode 100644 index 00000000..83de2c4c --- /dev/null +++ b/pom.xml.orig @@ -0,0 +1,110 @@ + + + 4.0.0 + + ru.fizteh.fivt.students + parent + 1.0-SNAPSHOT + pom + + fizteh-java-2015 + https://github.com/akormushin/fizteh-java-2015 + + + Travis CI + https://travis-ci.org/akormushin/fizteh-java-2015 + + + + UTF-8 + + + + akormushin +<<<<<<< HEAD + ocksumoron + +======= + thefacetakt +>>>>>>> 55f6bcabe5b6c104df8e320acb435f0b6e9425b5 + + + + + junit + junit + 4.12 + test + + + + org.mockito + mockito-core + 1.10.19 + test + + + + org.hamcrest + hamcrest-all + 1.3 + test + + + + com.tngtech.java + junit-dataprovider + 1.10.1 + test + + + + + + + maven-compiler-plugin + 3.2 + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 2.16 + + + validate + validate + + checkstyle.xml + UTF-8 + true + true + + + check + + + + + + com.puppycrawl.tools + checkstyle + 6.10.1 + + + + + + + + https://github.com/akormushin/fizteh-java-2015.git + scm:git:ssh://git@github.com/fizteh-java-2015.git + scm:git:ssh://git@github.com/fizteh-java-2015.git + HEAD + + + diff --git a/roller145/src/main/resources/twitter4j.properties b/roller145/src/main/resources/twitter4j.properties index 0e392da9..69154a31 100644 --- a/roller145/src/main/resources/twitter4j.properties +++ b/roller145/src/main/resources/twitter4j.properties @@ -1,5 +1,5 @@ debug=true -oauth.consumerKey=buGhiLsAfMeGLgIykUUzUS7R7 -oauth.consumerSecret=yl1bi2Dg691i6uWC3EdsFImrbhmeWUprdBfayC2PWUWwCPMlcC -oauth.accessToken=3665688383-3jixN3Szt0gtyUJAw6mlgZSGRPO7rRxXvCzxUPu -oauth.accessTokenSecret=YLk7pdOGSqLhLuBNUcv46tfX12UyP4pFeAitcA1lICts5 +oauth.consumerKey=Iflj8RPdRnBp0efOh3745QKUa +oauth.consumerSecret=90PMn7liXFzrpkuDGssrglrufdoXHoqjdoGZgk0ph64mNX6k0Q +oauth.accessToken=311643835-DnJaH2agWHJiqr06xQcUJ9f17UDBCLXl8OxectqS +oauth.accessTokenSecret=HzRIMTq767cZpi4AlSkOJhNYHz8dXxqj1ZakdZ4QuAtON \ No newline at end of file